00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef INCLUDE_DBM_PARTITION_H
00015 #define INCLUDE_DBM_PARTITION_H
00016
00017 #include "dbm/fed.h"
00018 #include "base/intutils.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 namespace dbm
00030 {
00031
00032
00033 class partition_t
00034 {
00035 public:
00036
00037
00038
00039 partition_t(cindex_t dim)
00040 : fedTable(dim2ptr(dim)) {}
00041
00042
00043 partition_t(const partition_t& arg)
00044 : fedTable(arg.fedTable) {
00045 assert(fedTable);
00046 if (isPtr()) fedTable->incRef();
00047 }
00048
00049
00050 partition_t& operator = (const partition_t& arg) {
00051 assert(fedTable);
00052 if (arg.isPtr()) arg.fedTable->incRef();
00053 if (isPtr()) fedTable->decRef();
00054 fedTable = arg.fedTable;
00055 return *this;
00056 }
00057
00058 ~partition_t() {
00059 assert(fedTable);
00060 if (isPtr()) fedTable->decRef();
00061 }
00062
00063
00064
00065 void intern();
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 void add(uintptr_t id, fed_t& fed);
00080
00081
00082
00083
00084
00085
00086 fed_t get(uint32_t id) const {
00087 assert(fedTable);
00088 return isPtr() ? fedTable->get(id) : fed_t(edim());
00089 }
00090
00091
00092 cindex_t getDimension() const {
00093 assert(fedTable);
00094 return isPtr() ? fedTable->getDimension() : edim();
00095 }
00096
00097
00098
00099 size_t getNumberOfDBMs() const {
00100 assert(fedTable);
00101 return isPtr() ? fedTable->getNumberOfDBMs() : 0;
00102 }
00103
00104
00105 class entry_t
00106 {
00107 public:
00108 entry_t(uint32_t i, const fed_t& f)
00109 : id(i), fed(f) {}
00110
00111 uint32_t id;
00112 fed_t fed;
00113 };
00114
00115
00116
00117
00118 class const_iterator
00119 {
00120 public:
00121
00122 const_iterator(const entry_t* const* start)
00123 : current(start) {}
00124
00125
00126 const fed_t& operator *() {
00127 assert(current && *current);
00128 return (*current)->fed;
00129 }
00130 const fed_t* operator ->() {
00131 assert(current && *current);
00132 return &(*current)->fed;
00133 }
00134
00135 bool isNull() const {
00136 assert(current);
00137 return *current == NULL;
00138 }
00139 uint32_t id() const {
00140 assert(current && *current);
00141 return (*current)->id;
00142 }
00143
00144 const_iterator& operator ++() {
00145 assert(current);
00146 ++current;
00147 return *this;
00148 }
00149
00150
00151
00152
00153
00154 bool operator == (const const_iterator& arg) const {
00155 return current == arg.current;
00156 }
00157 bool operator != (const const_iterator& arg) const {
00158 return !(*this == arg);
00159 }
00160 bool operator < (const const_iterator& arg) const {
00161 return current < arg.current;
00162 }
00163
00164 private:
00165 const entry_t* const* current;
00166 };
00167
00168
00169 const_iterator begin() const {
00170 assert(fedTable);
00171 return isPtr()
00172 ? const_iterator(fedTable->getBeginTable())
00173 : const_iterator(NULL);
00174 }
00175 const_iterator end() const {
00176 assert(fedTable);
00177 return isPtr()
00178 ? const_iterator(fedTable->getEndTable())
00179 : const_iterator(NULL);
00180 }
00181
00182 private:
00183
00184
00185
00186 class fedtable_t
00187 {
00188 public:
00189 static fedtable_t* create(cindex_t dim);
00190
00191
00192
00193 fedtable_t* copy();
00194
00195 void incRef() {
00196 refCounter++;
00197 }
00198 void decRef() {
00199 assert(refCounter > 0);
00200 if (!--refCounter) {
00201 remove();
00202 }
00203 }
00204 bool isMutable() {
00205 assert(refCounter > 0);
00206 return refCounter == 1;
00207 }
00208
00209
00210 entry_t** getTable() { return table; }
00211 const entry_t* const* getBeginTable() const { return table; }
00212 const entry_t* const* getEndTable() const { return getBeginTable() + getSize(); }
00213 cindex_t getDimension() const { return all.getDimension(); }
00214 size_t getSize() const { return mask + 1; }
00215
00216
00217 void remove();
00218
00219
00220
00221 fed_t get(uint32_t id) const;
00222
00223
00224
00225 bool add(uint32_t id, fed_t& fed);
00226
00227
00228
00229
00230 fedtable_t* larger();
00231
00232
00233 size_t getNumberOfDBMs() const;
00234
00235 private:
00236
00237 enum {
00238 INIT_POWER = 1,
00239 INIT_SIZE = (1 << INIT_POWER),
00240 INIT_MASK = (INIT_SIZE - 1)
00241 };
00242
00243
00244 fedtable_t(cindex_t d, size_t nb, uint32_t m)
00245 : refCounter(1), all(d), nbEntries(nb), mask(m) {
00246
00247 }
00248
00249
00250 fedtable_t(cindex_t d)
00251 : refCounter(1), all(d), nbEntries(0), mask(INIT_MASK) {
00252 base_resetSmall(table, INIT_SIZE);
00253 }
00254
00255 uint32_t refCounter;
00256 fed_t all;
00257 size_t nbEntries;
00258 uint32_t mask;
00259 entry_t *table[];
00260 };
00261
00262
00263
00264 void checkMutable() {
00265 assert(fedTable);
00266 if (!fedTable->isMutable()) {
00267 fedTable = fedTable->copy();
00268 }
00269 }
00270
00271 static fedtable_t* dim2ptr(cindex_t dim) {
00272 return (fedtable_t*) ((dim << 1) | 1);
00273 }
00274 bool isPtr() const {
00275 return (((uintptr_t)fedTable) & 1) == 0;
00276 }
00277 cindex_t edim() const {
00278 assert(!isPtr());
00279 return ((uintptr_t)fedTable) >> 1;
00280 }
00281
00282 fedtable_t *fedTable;
00283 };
00284 }
00285
00286 #endif // INCLUDE_DBM_PARTITION_H