00001 #ifndef PROJECTEDEVENTSHEAPBUFFER_H_
00002 #define PROJECTEDEVENTSHEAPBUFFER_H_
00003
00004 #include "globals.h"
00005 #include "EvSimObject.h"
00006
00007 #include <vector>
00008 using std::vector;
00009
00010 #include <utility>
00011
00012 #include "binaryheap.h"
00013
00014
00015 class ProjectedEventsHeapBuffer {
00016 public:
00017
00018 ProjectedEventsHeapBuffer();
00019 virtual ~ProjectedEventsHeapBuffer();
00020
00021 static const int invalid_heap_pos = -1;
00022
00023
00024 size_t registerProjectedOutPorts(EvSimObject* sender);
00025
00026
00027 void setGlobalOutputPort(global_proj_out_port_id_t proj_port_id, global_out_port_id_t global_out_port_id);
00028
00029 void makeHeap();
00030
00031 void update(global_proj_out_port_id_t port, Time newtime);
00032
00033 void updateTop(Time newtime);
00034
00035 std::pair<EvSimObject *, global_out_port_id_t> topSender();
00036
00037 Time topTime();
00038
00039 bool empty() const {
00040 return projected_port_vec.empty();
00041 }
00042
00043 size_t size() {
00044 return projected_port_vec.size();
00045 }
00046
00047 protected:
00048
00049 struct Node {
00050 Node(EvSimObject * sender_obj) :
00051 sender_obj(sender_obj), time(MAX_TIME), heap_pos(invalid_heap_pos) {};
00052 EvSimObject* sender_obj;
00053 global_out_port_id_t global_port_id;
00054 Time time;
00055 int heap_pos;
00056 };
00057
00058
00059 class NodeCompare {
00060 public:
00061 bool operator()(Node const * left, Node const * right) const {
00062 return left->time > right->time;
00063 }
00064 };
00065
00066 class HeapPosUpdater {
00067 public:
00068 void operator()(Node *n, unsigned pos) {
00069 n->heap_pos = pos;
00070 }
00071 };
00072
00073 vector<Node *> heap_vec;
00074
00075 vector<Node> projected_port_vec;
00076
00077 };
00078
00079
00080 inline size_t ProjectedEventsHeapBuffer::registerProjectedOutPorts(EvSimObject * sender)
00081 {
00082 size_t prev_size = projected_port_vec.size();
00083 size_t num_ports = sender->numProjOutputPorts();
00084 projected_port_vec.resize(prev_size + num_ports, Node(sender));
00085 return prev_size;
00086 }
00087
00088 inline void ProjectedEventsHeapBuffer::makeHeap()
00089 {
00090 vector<Node>::iterator proj_vec_it = projected_port_vec.begin();
00091 heap_vec.reserve(projected_port_vec.size());
00092 for ( ; proj_vec_it != projected_port_vec.end() ; ++proj_vec_it) {
00093 proj_vec_it->heap_pos = heap_vec.size();
00094 heap_vec.push_back(&(*proj_vec_it));
00095 }
00096 std::make_heap(heap_vec.begin(), heap_vec.end(), NodeCompare(), HeapPosUpdater());
00097 }
00098
00099 inline void ProjectedEventsHeapBuffer::update(global_proj_out_port_id_t port_id, Time newtime)
00100 {
00101 projected_port_vec[port_id].time= newtime;
00102 std::update_heap_pos(heap_vec.begin(), heap_vec.end(),
00103 heap_vec.begin() + projected_port_vec[port_id].heap_pos, NodeCompare(), HeapPosUpdater());
00104 }
00105
00106 inline void ProjectedEventsHeapBuffer::updateTop(Time newtime) {
00107 global_proj_out_port_id_t port_id = heap_vec[0] - &projected_port_vec[0];
00108 update(port_id, newtime);
00109 }
00110
00111 inline std::pair<EvSimObject *, global_out_port_id_t> ProjectedEventsHeapBuffer::topSender() {
00112 return std::make_pair(heap_vec[0]->sender_obj, heap_vec[0]->global_port_id);
00113 }
00114
00115
00116 inline Time ProjectedEventsHeapBuffer::topTime() {
00117 return heap_vec[0]->time;
00118 }
00119
00120
00121 #endif