7 DynamicMemoryDataCache::DynamicMemoryDataCache() {
8 m_treeHeadVector
.push_back(new TreeHead(0));
9 std::cout
<< "m_treeHeadVector.size(): " << m_treeHeadVector
.size() << std::endl
;
12 DynamicMemoryDataCache::~DynamicMemoryDataCache() {
16 void DynamicMemoryDataCache::processPacket(DataPacket
*packet
) {
17 uint8_t type
= *(uint8_t *)packet
->data
;
21 memcpy(&address
, (uint8_t *)packet
->data
+ 1, sizeof(address
));
23 memcpy(&nmemb
, (uint8_t *)packet
->data
+ 9, sizeof(nmemb
));
24 memcpy(&size
, (uint8_t *)packet
->data
+ 17, sizeof(size
));
25 allocBlock(address
, nmemb
* size
, packet
->dataSource
.timestamp
);
29 memcpy(&address
, (uint8_t *)packet
->data
+ 1, sizeof(address
));
31 memcpy(&size
, (uint8_t *)packet
->data
+ 9, sizeof(size
));
33 /*std::cout << "malloc(" << size << "): 0x" << std::hex << address << std::dec << std::endl;*/
34 allocBlock(address
, size
, packet
->dataSource
.timestamp
);
38 memcpy(&address
, (uint8_t *)packet
->data
+ 1, sizeof(address
));
39 /*std::cout << "free(0x" << std::hex << address << std::dec << ")" << std::endl;*/
41 freeBlock(address
, packet
->dataSource
.timestamp
);
44 /* TODO: implement this. */
45 std::cout
<< "realloc currently NYI." << std::endl
;
48 /* TODO: softcode this limit. */
49 if(latestTree()->changedList().size() > 500) {
50 std::cout
<< ">500 events in tree, creating new head . . ." << std::endl
;
55 static bool compareHeads(TreeHead
*one
, TreeHead
*two
) {
56 return one
->timestamp() < two
->timestamp();
59 static bool compareBlocks(Block
*one
, Block
*two
) {
60 return one
->allocTime() < two
->allocTime();
63 void DynamicMemoryDataCache::visit(const DataRange
&dataRange
, CacheVisitor
*visitor
) {
65 th
.updateTimestamp(dataRange
.beginTime());
66 TreeHeadVector::const_iterator startHead
= std::lower_bound(m_treeHeadVector
.begin(), m_treeHeadVector
.end(), &th
, compareHeads
);
68 if(startHead
== m_treeHeadVector
.end()) {
69 /* The range is out of range. */
73 th
.updateTimestamp(dataRange
.endTime());
74 TreeHeadVector::const_iterator endHead
= std::upper_bound(m_treeHeadVector
.begin(), m_treeHeadVector
.end(), &th
, compareHeads
);
76 class RecursiveTraversal
{
78 CacheVisitor
*m_visitor
;
79 Timestamp m_lowerCutoff
;
80 Timestamp m_upperCutoff
;
82 void traverse(TreeNode
*node
) {
83 if(node
== NULL
) return;
85 if(node
->left()) traverse(node
->left());
86 if(node
->right()) traverse(node
->right());
88 Block
*block
= node
->data();
89 if(!(block
->allocTime() > m_upperCutoff
90 || block
->releaseTime() < m_lowerCutoff
)) m_visitor
->handleBlock(node
->data());
95 traverser
.m_lowerCutoff
= dataRange
.beginTime();
96 traverser
.m_upperCutoff
= dataRange
.endTime();
97 traverser
.m_visitor
= visitor
;
99 traverser
.traverse((*startHead
)->headNode());
101 Block
block(0, 0, dataRange
.beginTime());
103 TreeHead::BlockList::const_iterator start
= std::lower_bound((*startHead
)->changedList().begin(), (*startHead
)->changedList().end(), &block
, compareBlocks
);
105 for(; start
!= (*startHead
)->changedList().end(); start
++) {
106 visitor
->handleBlock((*start
));
109 if(startHead
== endHead
) return;
113 for(; startHead
!= endHead
; startHead
++) {
114 for(TreeHead::BlockList::const_iterator i
= (*startHead
)->changedList().begin();
115 i
!= (*startHead
)->changedList().end() && (*i
)->allocTime() < dataRange
.endTime(); i
++) {
117 visitor
->handleBlock(*i
);
123 void DynamicMemoryDataCache::newHead() {
124 TreeHead
*head
= new TreeHead(m_treeHeadVector
.size());
125 head
->attachTo(m_treeHeadVector
.back());
126 m_treeHeadVector
.push_back(head
);
129 void DynamicMemoryDataCache::allocBlock(uint64_t address
, uint64_t size
, Timestamp timestamp
) {
130 TreeNode
*node
= latestTree()->create(address
);
134 node
= latestTree()->create(address
);
137 Block
*block
= new Block(address
, size
, timestamp
);
139 node
->setData(block
);
140 latestTree()->appendChanged(block
);
141 latestTree()->updateTimestamp(timestamp
);
144 void DynamicMemoryDataCache::freeBlock(uint64_t address
, Timestamp timestamp
) {
145 TreeNode
*node
= latestTree()->lookup(address
);
146 if(node
== NULL
) return;
147 if(!latestTree()->remove(address
)) {
149 latestTree()->remove(address
);
151 node
->data()->setReleaseTime(timestamp
);
152 latestTree()->appendChanged(node
->data());
153 latestTree()->updateTimestamp(timestamp
);
156 DataRange
DynamicMemoryDataCache::densityRange() const {
157 /* TODO: calculate total time and data range. (step through each?) */
158 return DataRange(m_treeHeadVector
.front()->changedList().front()->allocTime(), m_treeHeadVector
.front()->changedList().front()->address(),
159 m_treeHeadVector
.front()->changedList().front()->releaseTime(), m_treeHeadVector
.front()->changedList().front()->address() + m_treeHeadVector
.front()->changedList().front()->size() + 128);