00001
00002
00003 #ifndef BUFFERED_NODE_H
00004 #define BUFFERED_NODE_H
00005
00006 #include "Node.h"
00007 #include "Buffer.h"
00008
00009 namespace FD {
00010
00011 class OutputCacheInfo {
00012 public:
00013 OutputCacheInfo ()
00014 : lookAhead(0)
00015 , lookBack(0)
00016 {}
00017
00018 RCPtr<Buffer> buffer;
00019 int lookAhead;
00020 int lookBack;
00021 };
00022
00023 class InputCacheInfo {
00024 public:
00025 InputCacheInfo ()
00026 : lookAhead(0)
00027 , lookBack(0)
00028 {}
00029 int lookAhead;
00030 int lookBack;
00031 };
00032
00034 class BufferedNode : public Node {
00035 protected:
00036
00037 int processCount;
00038
00039 std::vector<OutputCacheInfo> outputs;
00040
00041 std::vector<InputCacheInfo> inputsCache;
00042
00044 bool inOrder;
00045 public:
00047 BufferedNode(std::string nodeName, const ParameterSet ¶ms);
00048
00050 virtual ~BufferedNode() {}
00051
00054 virtual ObjectRef getOutput(int output_id, int count);
00055
00058 virtual void calculate(int output_id, int count, Buffer &buf) = 0;
00059
00061 virtual void request(int outputID, const ParameterSet &req);
00062
00063
00064
00067 virtual void initialize();
00068
00070 virtual void reset();
00071
00073 virtual int addOutput (const std::string &outputName);
00074
00076 virtual int addInput (const std::string &inputName);
00077
00078
00079 virtual void initializeBuffers();
00080
00081
00082 virtual void performRequests();
00083
00084 protected:
00086 BufferedNode() {throw new GeneralException("BufferedNode copy constructor should not be called",__FILE__,__LINE__);}
00087 };
00088
00089 #ifdef ENABLE_SPEED_HACKS
00090
00091 #define NO_ORDER_NODE_SPEEDUP(nodeClass) \
00092 ObjectRef getOutput(int output_id, int count) \
00093 { \
00094 Buffer &outBuffer = *(outputs[output_id].buffer); \
00095 if (!outBuffer.isValid(count)) \
00096 nodeClass::calculate (output_id, count, outBuffer);\
00097 return outBuffer.get(count);}
00098
00099 #define IN_ORDER_NODE_SPEEDUP(nodeClass) \
00100 ObjectRef getOutput(int output_id, int count) \
00101 { \
00102 Buffer &outBuffer = *(outputs[output_id].buffer); \
00103 for (int i=processCount+1;i<=count;i++) \
00104 nodeClass::calculate(output_id, i, outBuffer); \
00105 if (count > processCount) \
00106 processCount = count; \
00107 return outBuffer.get(count); \
00108 }
00109
00110
00111 #else
00112
00113
00114 #define NO_ORDER_NODE_SPEEDUP(nodeClass) \
00115 ObjectRef getOutput(int output_id, int count) \
00116 { \
00117 try { \
00118 Buffer &outBuffer = *(outputs[output_id].buffer); \
00119 if (!outBuffer.isValid(count)) \
00120 nodeClass::calculate (output_id, count, outBuffer);\
00121 return outBuffer.get(count); \
00122 } catch (BaseException *e) \
00123 { \
00124 throw e->add(new NodeException (this, "Exception caught in BufferedNode::getOutput", __FILE__, __LINE__));\
00125 } \
00126 }
00127
00128 #define IN_ORDER_NODE_SPEEDUP(nodeClass) \
00129 ObjectRef getOutput(int output_id, int count) \
00130 { \
00131 try { \
00132 Buffer &outBuffer = *(outputs[output_id].buffer); \
00133 for (int i=processCount+1;i<=count;i++) \
00134 nodeClass::calculate(output_id, i, outBuffer); \
00135 if (count > processCount) \
00136 processCount = count; \
00137 return outBuffer.get(count); \
00138 } catch (BaseException *e) \
00139 { \
00140 throw e->add(new NodeException (this, "Exception caught in BufferedNode::getOutput", __FILE__, __LINE__));\
00141 } \
00142 }
00143
00144
00145 #endif
00146
00147 }
00148
00149 #endif