Fixed two query bugs:

* For B_EQUALS queries the first match would be skipped.
* Exact entry name matches were broken, since the used NameIndex::Find()
  expected null-terminated keys with the \0 included in the key length
  while it was fed only the raw string length.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20306 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-03-02 11:18:14 +00:00
parent 2f742879c8
commit bb7ddc43d3
2 changed files with 23 additions and 6 deletions
@@ -189,8 +189,21 @@ NameIndex::InternalGetIterator()
AbstractIndexEntryIterator * AbstractIndexEntryIterator *
NameIndex::InternalFind(const uint8 *key, size_t length) NameIndex::InternalFind(const uint8 *key, size_t length)
{ {
if (!key || length == 0 || key[length - 1] != '\0') if (!key || length == 0)
return NULL; return NULL;
// if the key is not null-terminated, copy it
uint8 clonedKey[kMaxIndexKeyLength];
if (key[length - 1] != '\0') {
if (length >= kMaxIndexKeyLength)
length = kMaxIndexKeyLength - 1;
memcpy(clonedKey, key, length);
clonedKey[length] = '\0';
length++;
key = clonedKey;
}
NameIndexEntryIterator *iterator = new(nothrow) NameIndexEntryIterator; NameIndexEntryIterator *iterator = new(nothrow) NameIndexEntryIterator;
if (iterator) { if (iterator) {
if (!iterator->SetTo(this, (const char *)key)) { if (!iterator->SetTo(this, (const char *)key)) {
@@ -96,6 +96,8 @@ IndexIterator::Find(const uint8 *const key, size_t keyLength)
{ {
status_t error = B_ENTRY_NOT_FOUND; status_t error = B_ENTRY_NOT_FOUND;
if (fIndexWrapper && fIndexWrapper->fIndex) { if (fIndexWrapper && fIndexWrapper->fIndex) {
// TODO: We actually don't want an exact Find() here, but rather a
// FindClose().
fInitialized = fIndexWrapper->fIndex->Find(key, keyLength, &fIterator); fInitialized = fIndexWrapper->fIndex->Find(key, keyLength, &fIterator);
if (fInitialized) if (fInitialized)
error = B_OK; error = B_OK;
@@ -110,20 +112,22 @@ IndexIterator::GetNextEntry(uint8 *buffer, uint16 *_keyLength,
{ {
status_t error = B_ENTRY_NOT_FOUND; status_t error = B_ENTRY_NOT_FOUND;
if (fIndexWrapper && fIndexWrapper->fIndex) { if (fIndexWrapper && fIndexWrapper->fIndex) {
// get next entry // init iterator, if not done yet
size_t keyLength; if (!fInitialized) {
if (fInitialized)
fIterator.GetNext();
else {
fIndexWrapper->fIndex->GetIterator(&fIterator); fIndexWrapper->fIndex->GetIterator(&fIterator);
fInitialized = true; fInitialized = true;
} }
// get key // get key
size_t keyLength;
if (Entry *entry = fIterator.GetCurrent(buffer, &keyLength)) { if (Entry *entry = fIterator.GetCurrent(buffer, &keyLength)) {
*_keyLength = keyLength; *_keyLength = keyLength;
*_entry = entry; *_entry = entry;
error = B_OK; error = B_OK;
} }
// get next entry
fIterator.GetNext();
} }
return error; return error;
} }