1 //-< HARRAY.H >------------------------------------------------------*--------* 2 // FastDB Version 1.0 (c) 1999 GARRET * ? * 3 // (Main Memory Database Management System) * /\| * 4 // * / \ * 5 // Created: 25-Mar-2003 K.A. Knizhnik * / [] \ * 6 // Last update: 25-Mar-2003 K.A. Knizhnik * GARRET * 7 //-------------------------------------------------------------------*--------* 8 // Hierarchical array 9 //-------------------------------------------------------------------*--------* 10 11 #ifndef __HARRAY_H__ 12 #define __HARRAY_H__ 13 14 BEGIN_FASTDB_NAMESPACE 15 16 #include "fastdb.h" 17 18 const size_t dbHArrayPageSize = dbPageSize / sizeof(oid_t); 19 20 #ifdef HAS_TEMPLATE_FRIENDS 21 template<class T> 22 class dbHArray : public dbAnyReference { 23 public: 24 enum { 25 leafPageSize = dbPageSize / sizeof(T), 26 maxArraySize = dbHArrayPageSize*dbHArrayPageSize*leafPageSize 27 }; 28 create(dbDatabase * db)29 void create(dbDatabase* db) { 30 db->beginTransaction(dbDatabase::dbExclusiveLock); 31 oid = db->allocateObject(dbPageObjectMarker); 32 memset(db->get(oid), 0, dbPageSize); 33 } 34 get(size_t i,dbDatabase * db)35 T get(size_t i, dbDatabase* db) const { 36 assert (oid != 0 && i < maxArraySize); 37 db->beginTransaction(dbDatabase::dbSharedLock); 38 oid_t* page = (oid_t*)db->get(oid); 39 oid_t pageOid = page[i / (dbHArrayPageSize*leafPageSize)]; 40 if (pageOid == 0) { 41 return 0; 42 } 43 page = (oid_t*)db->get(pageOid); 44 pageOid = page[i / leafPageSize % dbHArrayPageSize]; 45 if (pageOid == 0) { 46 return 0; 47 } 48 T* leaf = (T*)db->get(pageOid); 49 return leaf[i % leafPageSize]; 50 } 51 set(size_t i,dbDatabase * db)52 T& set(size_t i, dbDatabase* db) { 53 assert (oid != 0 && i < maxArraySize); 54 db->beginTransaction(dbDatabase::dbExclusiveLock); 55 oid_t* page = (oid_t*)db->get(oid); 56 oid_t pageOid = page[i / (dbHArrayPageSize*leafPageSize)]; 57 if (pageOid == 0) { 58 pageOid = db->allocateObject(dbPageObjectMarker); 59 page = (oid_t*)db->put(oid); 60 page[i / (dbHArrayPageSize*leafPageSize)] = pageOid; 61 page = (oid_t*)db->get(pageOid); 62 memset(page, 0, dbPageSize); 63 } else { 64 page = (oid_t*)db->get(pageOid); 65 } 66 oid_t leafPageOid = page[i / leafPageSize % dbHArrayPageSize]; 67 T* leaf; 68 if (leafPageOid == 0) { 69 leafPageOid = db->allocateObject(dbPageObjectMarker); 70 page = (oid_t*)db->put(pageOid); 71 page[i / leafPageSize % dbHArrayPageSize] = leafPageOid; 72 leaf = (T*)db->get(leafPageOid); 73 memset(leaf, 0, dbPageSize); 74 } else { 75 leaf = (T*)db->put(leafPageOid); 76 } 77 return leaf[i % leafPageSize]; 78 } 79 set(size_t i,T value,dbDatabase * db)80 void set(size_t i, T value, dbDatabase* db) { 81 set(i, db) = value; 82 } 83 }; 84 #else 85 class dbAnyHArray : public dbAnyReference { 86 public: create(dbDatabase * db)87 void create(dbDatabase* db) { 88 db->beginTransaction(dbDatabase::dbExclusiveLock); 89 oid = db->allocateObject(dbPageObjectMarker); 90 memset(db->get(oid), 0, dbPageSize); 91 } 92 get(size_t i,dbDatabase * db,const size_t maxArraySize,const size_t leafPageSize)93 byte* get(size_t i, dbDatabase* db, const size_t maxArraySize, const size_t leafPageSize) const { 94 assert (oid != 0 && i < maxArraySize); 95 db->beginTransaction(dbDatabase::dbSharedLock); 96 oid_t* page = (oid_t*)db->get(oid); 97 oid_t pageOid = page[i / (dbHArrayPageSize*leafPageSize)]; 98 if (pageOid == 0) { 99 return 0; 100 } 101 page = (oid_t*)db->get(pageOid); 102 pageOid = page[i / leafPageSize % dbHArrayPageSize]; 103 if (pageOid == 0) { 104 return 0; 105 } 106 return db->get(pageOid); 107 } 108 set(size_t i,dbDatabase * db,const size_t maxArraySize,const size_t leafPageSize)109 byte* set(size_t i, dbDatabase* db, const size_t maxArraySize, const size_t leafPageSize) { 110 assert (oid != 0 && i < maxArraySize); 111 db->beginTransaction(dbDatabase::dbExclusiveLock); 112 oid_t* page = (oid_t*)db->get(oid); 113 oid_t pageOid = page[i / (dbHArrayPageSize*leafPageSize)]; 114 if (pageOid == 0) { 115 pageOid = db->allocateObject(dbPageObjectMarker); 116 page = (oid_t*)db->put(oid); 117 page[i / (dbHArrayPageSize*leafPageSize)] = pageOid; 118 page = (oid_t*)db->get(pageOid); 119 memset(page, 0, dbPageSize); 120 } else { 121 page = (oid_t*)db->get(pageOid); 122 } 123 oid_t leafPageOid = page[i / leafPageSize % dbHArrayPageSize]; 124 byte* leaf; 125 if (leafPageOid == 0) { 126 leafPageOid = db->allocateObject(dbPageObjectMarker); 127 page = (oid_t*)db->put(pageOid); 128 page[i / leafPageSize % dbHArrayPageSize] = leafPageOid; 129 leaf = db->get(leafPageOid); 130 memset(leaf, 0, dbPageSize); 131 } else { 132 leaf = db->put(leafPageOid); 133 } 134 return leaf; 135 } 136 }; 137 138 template<class T> 139 class dbHArray : public dbAnyHArray { 140 public: 141 enum { 142 leafPageSize = dbPageSize / sizeof(T), 143 maxArraySize = dbHArrayPageSize*dbHArrayPageSize*leafPageSize 144 }; 145 set(size_t i,T value,dbDatabase * db)146 void set(size_t i, T value, dbDatabase* db) { 147 set(i, db) = value; 148 } get(size_t i,dbDatabase * db)149 T get(size_t i, dbDatabase* db) const { 150 return ((T*)dbAnyHArray::get(i, db, maxArraySize, leafPageSize))[i % leafPageSize]; 151 } set(size_t i,dbDatabase * db)152 T& set(size_t i, dbDatabase* db) { 153 return ((T*)dbAnyHArray::set(i, db, maxArraySize, leafPageSize))[i % leafPageSize]; 154 } 155 }; 156 #endif 157 158 159 160 161 class dbBitmap : public dbHArray<int4> { 162 typedef dbHArray<int4> base; 163 public: create(dbDatabase * db)164 void create(dbDatabase* db) { 165 base::create(db); 166 } 167 get(size_t i,dbDatabase * db)168 bool get(size_t i, dbDatabase* db) const { 169 return (base::get(i >> 5, db) & (1 << (i & 31))) != 0; 170 } 171 set(size_t i,bool value,dbDatabase * db)172 void set(size_t i, bool value, dbDatabase* db) { 173 int4& mask = base::set(i >> 5, db); 174 if (value) { 175 mask |= 1 << (i & 31); 176 } else { 177 mask &= ~(1 << (i & 31)); 178 } 179 } 180 }; 181 182 END_FASTDB_NAMESPACE 183 184 #endif 185 186