00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __HARRAY_H__
00012 #define __HARRAY_H__
00013
00014 BEGIN_FASTDB_NAMESPACE
00015
00016 #include "fastdb.h"
00017
00018 const size_t dbHArrayPageSize = dbPageSize / sizeof(oid_t);
00019
00020 #ifdef HAS_TEMPLATE_FRIENDS
00021 template<class T>
00022 class dbHArray : public dbAnyReference {
00023 public:
00024 enum {
00025 leafPageSize = dbPageSize / sizeof(T),
00026 maxArraySize = dbHArrayPageSize*dbHArrayPageSize*leafPageSize
00027 };
00028
00029 void create(dbDatabase* db) {
00030 db->beginTransaction(dbDatabase::dbExclusiveLock);
00031 oid = db->allocateObject(dbPageObjectMarker);
00032 memset(db->get(oid), 0, dbPageSize);
00033 }
00034
00035 T get(size_t i, dbDatabase* db) const {
00036 assert (oid != 0 && i < maxArraySize);
00037 db->beginTransaction(dbDatabase::dbSharedLock);
00038 oid_t* page = (oid_t*)db->get(oid);
00039 oid_t pageOid = page[i / (dbHArrayPageSize*leafPageSize)];
00040 if (pageOid == 0) {
00041 return 0;
00042 }
00043 page = (oid_t*)db->get(pageOid);
00044 pageOid = page[i / leafPageSize % dbHArrayPageSize];
00045 if (pageOid == 0) {
00046 return 0;
00047 }
00048 T* leaf = (T*)db->get(pageOid);
00049 return leaf[i % leafPageSize];
00050 }
00051
00052 T& set(size_t i, dbDatabase* db) {
00053 assert (oid != 0 && i < maxArraySize);
00054 db->beginTransaction(dbDatabase::dbExclusiveLock);
00055 oid_t* page = (oid_t*)db->get(oid);
00056 oid_t pageOid = page[i / (dbHArrayPageSize*leafPageSize)];
00057 if (pageOid == 0) {
00058 pageOid = db->allocateObject(dbPageObjectMarker);
00059 page = (oid_t*)db->put(oid);
00060 page[i / (dbHArrayPageSize*leafPageSize)] = pageOid;
00061 page = (oid_t*)db->get(pageOid);
00062 memset(page, 0, dbPageSize);
00063 } else {
00064 page = (oid_t*)db->get(pageOid);
00065 }
00066 oid_t leafPageOid = page[i / leafPageSize % dbHArrayPageSize];
00067 T* leaf;
00068 if (leafPageOid == 0) {
00069 leafPageOid = db->allocateObject(dbPageObjectMarker);
00070 page = (oid_t*)db->put(pageOid);
00071 page[i / leafPageSize % dbHArrayPageSize] = leafPageOid;
00072 leaf = (T*)db->get(leafPageOid);
00073 memset(leaf, 0, dbPageSize);
00074 } else {
00075 leaf = (T*)db->put(leafPageOid);
00076 }
00077 return leaf[i % leafPageSize];
00078 }
00079
00080 void set(size_t i, T value, dbDatabase* db) {
00081 set(i, db) = value;
00082 }
00083 };
00084 #else
00085 class dbAnyHArray : public dbAnyReference {
00086 public:
00087 void create(dbDatabase* db) {
00088 db->beginTransaction(dbDatabase::dbExclusiveLock);
00089 oid = db->allocateObject(dbPageObjectMarker);
00090 memset(db->get(oid), 0, dbPageSize);
00091 }
00092
00093 byte* get(size_t i, dbDatabase* db, const size_t maxArraySize, const size_t leafPageSize) const {
00094 assert (oid != 0 && i < maxArraySize);
00095 db->beginTransaction(dbDatabase::dbSharedLock);
00096 oid_t* page = (oid_t*)db->get(oid);
00097 oid_t pageOid = page[i / (dbHArrayPageSize*leafPageSize)];
00098 if (pageOid == 0) {
00099 return 0;
00100 }
00101 page = (oid_t*)db->get(pageOid);
00102 pageOid = page[i / leafPageSize % dbHArrayPageSize];
00103 if (pageOid == 0) {
00104 return 0;
00105 }
00106 return db->get(pageOid);
00107 }
00108
00109 byte* set(size_t i, dbDatabase* db, const size_t maxArraySize, const size_t leafPageSize) {
00110 assert (oid != 0 && i < maxArraySize);
00111 db->beginTransaction(dbDatabase::dbExclusiveLock);
00112 oid_t* page = (oid_t*)db->get(oid);
00113 oid_t pageOid = page[i / (dbHArrayPageSize*leafPageSize)];
00114 if (pageOid == 0) {
00115 pageOid = db->allocateObject(dbPageObjectMarker);
00116 page = (oid_t*)db->put(oid);
00117 page[i / (dbHArrayPageSize*leafPageSize)] = pageOid;
00118 page = (oid_t*)db->get(pageOid);
00119 memset(page, 0, dbPageSize);
00120 } else {
00121 page = (oid_t*)db->get(pageOid);
00122 }
00123 oid_t leafPageOid = page[i / leafPageSize % dbHArrayPageSize];
00124 byte* leaf;
00125 if (leafPageOid == 0) {
00126 leafPageOid = db->allocateObject(dbPageObjectMarker);
00127 page = (oid_t*)db->put(pageOid);
00128 page[i / leafPageSize % dbHArrayPageSize] = leafPageOid;
00129 leaf = db->get(leafPageOid);
00130 memset(leaf, 0, dbPageSize);
00131 } else {
00132 leaf = db->put(leafPageOid);
00133 }
00134 return leaf;
00135 }
00136 };
00137
00138 template<class T>
00139 class dbHArray : public dbAnyHArray {
00140 public:
00141 enum {
00142 leafPageSize = dbPageSize / sizeof(T),
00143 maxArraySize = dbHArrayPageSize*dbHArrayPageSize*leafPageSize
00144 };
00145
00146 void set(size_t i, T value, dbDatabase* db) {
00147 set(i, db) = value;
00148 }
00149 T get(size_t i, dbDatabase* db) const {
00150 return ((T*)dbAnyHArray::get(i, db, maxArraySize, leafPageSize))[i % leafPageSize];
00151 }
00152 T& set(size_t i, dbDatabase* db) {
00153 return ((T*)dbAnyHArray::set(i, db, maxArraySize, leafPageSize))[i % leafPageSize];
00154 }
00155 };
00156 #endif
00157
00158
00159
00160
00161 class dbBitmap : public dbHArray<int4> {
00162 typedef dbHArray<int4> base;
00163 public:
00164 void create(dbDatabase* db) {
00165 base::create(db);
00166 }
00167
00168 bool get(size_t i, dbDatabase* db) const {
00169 return (base::get(i >> 5, db) & (1 << (i & 31))) != 0;
00170 }
00171
00172 void set(size_t i, bool value, dbDatabase* db) {
00173 int4& mask = base::set(i >> 5, db);
00174 if (value) {
00175 mask |= 1 << (i & 31);
00176 } else {
00177 mask &= ~(1 << (i & 31));
00178 }
00179 }
00180 };
00181
00182 END_FASTDB_NAMESPACE
00183
00184 #endif
00185