BFS B+tree test: use set to ensure string uniqueness.

* The previous solution was rather slow, and also could produce
  duplicates under some circumstance.
This commit is contained in:
Axel Dörfler
2015-01-15 20:30:50 +01:00
parent 9b61a43ad6
commit 7fb1396861
@@ -7,6 +7,9 @@
//! BFS B+Tree torture test //! BFS B+Tree torture test
#include <set>
#include <string>
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -179,12 +182,7 @@ dumpKeys()
void void
generateName(int32 i, char* name, int32* _length) generateName(int32 i, char* name, int32* _length)
{ {
// We're using the index position as a hint for the length int32 length = rand() % (MAX_STRING - MIN_STRING) + MIN_STRING;
// of the string - this way, it's much less expansive to
// test for string uniqueness.
// We don't want to sort the strings to have more realistic
// access patterns to the tree (only true for the strings test).
int32 length = i % (MAX_STRING - MIN_STRING) + MIN_STRING;
for (int32 i = 0; i < length; i++) { for (int32 i = 0; i < length; i++) {
int32 c = int32(52.0 * rand() / RAND_MAX); int32 c = int32(52.0 * rand() / RAND_MAX);
if (c >= 26) if (c >= 26)
@@ -244,18 +242,6 @@ fillBuffer(void* buffer, int32 start)
} }
bool
findKey(void* key, int32 length, int32 maxIndex)
{
for (int32 i = length; i < maxIndex; i += MAX_STRING - MIN_STRING) {
if (length == (int32)gKeys[i].length
&& !memcpy(key, gKeys[i].data, length))
return true;
}
return false;
}
status_t status_t
createKeys() createKeys()
{ {
@@ -264,18 +250,23 @@ createKeys()
return B_NO_MEMORY; return B_NO_MEMORY;
if (gType == S_STR_INDEX) { if (gType == S_STR_INDEX) {
std::set<std::string> set;
for (int32 i = 0; i < gNum; i++) { for (int32 i = 0; i < gNum; i++) {
char name[B_FILE_NAME_LENGTH]; char name[B_FILE_NAME_LENGTH];
int32 length; int32 length;
int32 tries = 0; int32 tries = 0;
bool last; std::set<std::string>::const_iterator found;
// create unique keys! // create unique keys!
do { while (tries++ < 100) {
generateName(i, name, &length); generateName(i, name, &length);
} while ((last = findKey(name, length, i)) && tries++ < 100); found = set.find(string(name));
if (found == set.end())
break;
}
if (last) { if (found != set.end()) {
printf("Couldn't create unique key list!\n"); printf("Couldn't create unique key list!\n");
dumpKeys(); dumpKeys();
bailOut(); bailOut();
@@ -287,6 +278,7 @@ createKeys()
gKeys[i].in = 0; gKeys[i].in = 0;
gKeys[i].count = 0; gKeys[i].count = 0;
gKeys[i].value = i; gKeys[i].value = i;
set.insert(name);
} }
} else { } else {
int32 length; int32 length;
@@ -437,8 +429,7 @@ addAllKeys(Transaction& transaction, BPlusTree* tree)
if (status != B_OK) { if (status != B_OK) {
printf("BPlusTree::Insert() returned: %s\n", strerror(status)); printf("BPlusTree::Insert() returned: %s\n", strerror(status));
printf("key: "); printf("key: ");
dumpKey(gKeys[i].data, gKeys[i].length); bailOutWithKey(gKeys[i].data, gKeys[i].length);
putchar('\n');
} else { } else {
gKeys[i].in++; gKeys[i].in++;
gTreeCount++; gTreeCount++;
@@ -779,7 +770,8 @@ main(int argc, char** argv)
transaction.Done(); transaction.Done();
// of course, we would have to free all our memory in a real application here... // Of course, we would have to free all our memory in a real application
// here...
// write the cache back to the tree // write the cache back to the tree
shutdown_cache(gVolume->Device(), gVolume->BlockSize()); shutdown_cache(gVolume->Device(), gVolume->BlockSize());