Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

lower branching factor

  • Loading branch information...
commit 8e5481161541f50d2b6be234dd15ed70b04270eb 1 parent b34d3a9
Albert Zeyer authored March 10, 2011

Showing 1 changed file with 35 additions and 30 deletions. Show diff stats Hide diff stats

  1. 65  DbFileBackend.cpp
65  DbFileBackend.cpp
@@ -176,47 +176,52 @@ struct DbFile_ValueChunk {
176 176
 
177 177
 struct DbFile_TreeChunk {
178 178
 	size_t selfOffset;
179  
-	DbFile_TreeChunk* parent;
180 179
 	uint64_t valueRef;
181  
-	uint64_t subtreeRefs[256];
  180
+	uint64_t subtreeRefs[4];
182 181
 	
183 182
 	DbFile_TreeChunk() {
184 183
 		selfOffset = 0;
185  
-		parent = NULL;
186 184
 		valueRef = 0;
187 185
 		memset(subtreeRefs, 0, sizeof(subtreeRefs));		
188 186
 	}
189 187
 	
190 188
 	Return getValue(DbFileBackend& db, const std::string& key, /*out*/DbFile_ValueChunk& value,
191 189
 					bool createIfNotExist = true, bool mustCreateNew = false) {
192  
-		if(key == "") {
193  
-			if(valueRef != 0) {
194  
-				if(mustCreateNew) return "entry does already exist";
195  
-				ASSERT( value.read(db, valueRef) );
196  
-				return true;
  190
+		DbFile_TreeChunk* curTree = this;
  191
+		DbFile_TreeChunk subtree;
  192
+		
  193
+		uint64_t bitOffset = 0;
  194
+		while(bitOffset < key.size()*8) {
  195
+			uint8_t next = key[bitOffset / 8];
  196
+			next >>= bitOffset % 8;
  197
+			next &= 3; // first 2 relevant bytes
  198
+			bitOffset += 2;
  199
+			
  200
+			if(curTree->subtreeRefs[next] != 0) {
  201
+				ASSERT( subtree.read(db, curTree->subtreeRefs[next]) );
  202
+				curTree = &subtree;
  203
+				continue;
197 204
 			}
198  
-			if(!createIfNotExist) return "entry not found: not set";
199  
-			valueRef = value.selfOffset = db.fileSize;
200  
-			ASSERT( write(db) );
201  
-			return true;
  205
+			
  206
+			if(!createIfNotExist) return "entry not found: subtree does not exist";
  207
+			
  208
+			DbFile_TreeChunk newSubtree;
  209
+			curTree->subtreeRefs[next] = newSubtree.selfOffset = db.fileSize;
  210
+			ASSERT( newSubtree.write(db) );
  211
+			ASSERT( curTree->write(db) );
  212
+			subtree = newSubtree;
  213
+			curTree = &subtree;
202 214
 		}
203 215
 		
204  
-		uint8_t next = (uint8_t)key[0];
205  
-		if(subtreeRefs[next] != 0) {
206  
-			DbFile_TreeChunk subtree;
207  
-			subtree.parent = this;
208  
-			ASSERT( subtree.read(db, subtreeRefs[next]) );
209  
-			return subtree.getValue(db, key.substr(1), value, createIfNotExist, mustCreateNew);
  216
+		if(curTree->valueRef != 0) {
  217
+			if(mustCreateNew) return "entry does already exist";
  218
+			ASSERT( value.read(db, curTree->valueRef) );
  219
+			return true;
210 220
 		}
211  
-		
212  
-		if(!createIfNotExist) return "entry not found: subtree does not exist";
213  
-		
214  
-		DbFile_TreeChunk subtree;
215  
-		subtree.parent = this;
216  
-		subtreeRefs[next] = subtree.selfOffset = db.fileSize;
217  
-		ASSERT( subtree.write(db) );
218  
-		ASSERT( write(db) );
219  
-		return subtree.getValue(db, key.substr(1), value, createIfNotExist, mustCreateNew);
  221
+		if(!createIfNotExist) return "entry not found: not set";
  222
+		curTree->valueRef = value.selfOffset = db.fileSize;
  223
+		ASSERT( curTree->write(db) );
  224
+		return true;
220 225
 	}
221 226
 		
222 227
 	Return write(DbFileBackend& db) {
@@ -225,7 +230,7 @@ struct DbFile_TreeChunk {
225 230
 
226 231
 		std::string data;		
227 232
 		data += rawString<uint64_t>(valueRef);
228  
-		for(short i = 0; i < 256; ++i)
  233
+		for(short i = 0; i < sizeof(subtreeRefs)/sizeof(subtreeRefs[0]); ++i)
229 234
 			data += rawString<uint64_t>(subtreeRefs[i]);
230 235
 		
231 236
 		data += rawString<uint32_t>(calc_crc(data));
@@ -244,7 +249,7 @@ struct DbFile_TreeChunk {
244 249
 		
245 250
 		size_t len = 0;
246 251
 		ASSERT( fread_bigendian<uint32_t>(db.file, len) );
247  
-		if(len != sizeof(uint64_t) * (/*valueRef*/1 + /*subtreeRefs*/256))
  252
+		if(len != sizeof(valueRef) + sizeof(subtreeRefs))
248 253
 			return "TreeChunk data size missmatch";
249 254
 		
250 255
 		std::string data(len, '\0');
@@ -260,7 +265,7 @@ struct DbFile_TreeChunk {
260 265
 		valueRef = valueFromRaw<uint64_t>(&data[offset]);
261 266
 		offset += sizeof(uint64_t);
262 267
 
263  
-		for(short i = 0; i < 256; ++i) {
  268
+		for(short i = 0; i < sizeof(subtreeRefs)/sizeof(subtreeRefs[0]); ++i) {
264 269
 			subtreeRefs[i] = valueFromRaw<uint64_t>(&data[offset]);
265 270
 			offset += sizeof(uint64_t);
266 271
 		}

0 notes on commit 8e54811

Please sign in to comment.
Something went wrong with that request. Please try again.