-
Notifications
You must be signed in to change notification settings - Fork 0
/
stRNode.h
153 lines (134 loc) · 3.65 KB
/
stRNode.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//
// File: stRNode.h
// Author: aocsa
//
// Created on January 17, 2007, 8:44 PM
//
#ifndef _stRNode_H
#define _stRNode_H
#include <arboretum/stTypes.h>
#include "stMBR.h"
#include "stHyperCube.h"
#define PAGE_SIZE 256
#define NODE_HEAD_SIZE sizeof(stRNode::stRNodeHeader)
#define ENTRY_SIZE sizeof(stRNode::stREntry)
class stRNode {
public:
struct stREntry {
stPageID PageID;
//stSize Offset;
stSize NEntries;
};
struct stRNodeHeader {
stCount Occupation;
stSize ObjSize;
stSize Order;
};
public:
stRNode(stPage* page, int order = 0) {
Page = page;
Header = (stRNodeHeader*)(Page->GetData());
Entries = (stREntry*)(Page->GetData() + sizeof(stRNodeHeader));
if(order != 0) {
Header->Occupation = 0;
Header->Order = order;
Header->ObjSize = OBJECT_SIZE;
}
}
int AddEntry(int objectSize, const stByte* obj, stPageID subTree ) {
Header->ObjSize = objectSize;
memcpy( this->Page->GetData() + GetFirstPosObject() + objectSize*Header->Occupation,
obj,
objectSize );
Entries[Header->Occupation].PageID = subTree;
++Header->Occupation;
return Header->Occupation - 1;
}
void SetEntry(int idx, int objectSize, const stByte* obj, stPageID subTree ) {
Header->ObjSize = objectSize;
memcpy( this->Page->GetData() + GetFirstPosObject() + objectSize*idx,
obj,
objectSize );
Entries[idx].PageID = subTree;
}
void RemoveEntry(int idx) {
assert(idx < GetNumberOfEntries());
// Update the usedSize
stCount i;
stCount lastID;
stSize rObjSize;
lastID = this->Header->Occupation - 1;
if (lastID != (unsigned int)idx){
rObjSize = GetObjectSize(idx);
// Let's move objects first. We will use memmove() from stdlib because
// it handles the overlap between src and dst. Remember that src is the
// offset of the last object and the dst is the offset of the last
// object plus removed object size.
memmove(Page->GetData() + GetFirstPosObject() + Header->ObjSize * (idx),
Page->GetData() + GetFirstPosObject() + Header->ObjSize * (idx + 1),
Header->ObjSize * (lastID - idx) );
// Let's move entries...
for (i = idx; i < lastID; i++){
// Copy all fields with memcpy (it's faster than field copy).
memcpy(Entries + i, Entries + i + 1, sizeof(stREntry));
}//end
}//end if
// Update counter...
Header->Occupation--;
}
stByte* GetObject(int idx) {
return this->Page->GetData() + GetFirstPosObject() + Header->ObjSize*idx;
}
stSize GetObjectSize(int idx) {
return Header->ObjSize;
}
stREntry& GetEntry(int idx) {
assert(idx < this->Header->Occupation);
return this->Entries[idx];
}
void SetNENtries(int idx, stCount NEntries) {
GetEntry(idx).NEntries = NEntries;
}
stCount GetNEntries(int idx) {
return GetEntry(idx).NEntries;
}
void RemoveAll() {
this->Header->Occupation = 0;
}
stCount GetNumberOfEntries() {
return this->Header->Occupation;
}
stCount GetTotalObjectCount() {
stCount sum = 0;
for (int i = 0; i < GetNumberOfEntries(); i++){
sum += GetNEntries(i);
}
return sum;
}
stPage* GetPage() {
return Page;
}
stPageID GetPageID() {
return this->Page->GetPageID();
}
bool IsOverflow() const {
return Header->Order < Header->Occupation;
}
int GetFirstPosObject () {
return sizeof(stRNodeHeader) + (this->Header->Order + 1)*sizeof(stREntry);
}
stSize GetNumberOfFreeObjects() {
stSize num = 0;
for (int i = 0; i < GetNumberOfEntries(); i++) {
if(Entries[i].PageID == 0){
num++;
}
}
return num;
}
protected:
stPage* Page;
stRNodeHeader* Header;
stREntry* Entries;
};
#endif /* _stRNode_H */