null+****@clear*****
null+****@clear*****
2011年 7月 4日 (月) 21:13:11 JST
Susumu Yata 2011-07-04 12:13:11 +0000 (Mon, 04 Jul 2011)
New Revision: 36d2b5279cde332376071f1fddefd57b58a1da84
Log:
fixed bugs of grn::dat::KeyCursor. 1. it returns the same key more than once. (with ASCENDING_CURSOR) 2. it does nothing if max == NULL. (with DESCENDING_CURSOR)
Modified files:
lib/dat/key-cursor.cpp
Modified: lib/dat/key-cursor.cpp (+30 -18)
===================================================================
--- lib/dat/key-cursor.cpp 2011-07-04 08:44:12 +0000 (fac4e34)
+++ lib/dat/key-cursor.cpp 2011-07-04 12:13:11 +0000 (f6d4afd)
@@ -121,9 +121,15 @@ void KeyCursor::ascending_init(const String &min_str, const String &max_str) {
}
}
+ if ((min_str.ptr() == NULL) || (min_str.length() == 0)) {
+ GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(ROOT_NODE_ID));
+ return;
+ }
+
UInt32 node_id = ROOT_NODE_ID;
- Node node = trie_->ith_node(node_id);
+ Node node;
for (UInt32 i = 0; i < min_str.length(); ++i) {
+ node = trie_->ith_node(node_id);
if (node.is_terminal()) {
Key key;
trie_->ith_key(node.key_id(), &key);
@@ -131,8 +137,14 @@ void KeyCursor::ascending_init(const String &min_str, const String &max_str) {
if ((result > 0) || ((result == 0) &&
((flags_ & EXCEPT_LOWER_BOUND) != EXCEPT_LOWER_BOUND))) {
GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node_id));
+ } else if (node.sibling() != INVALID_LABEL) {
+ GRN_DAT_THROW_IF(MEMORY_ERROR,
+ !buf_.push_back(node_id ^ node.label() ^ node.sibling()));
}
return;
+ } else if (node.sibling() != INVALID_LABEL) {
+ GRN_DAT_THROW_IF(MEMORY_ERROR,
+ !buf_.push_back(node_id ^ node.label() ^ node.sibling()));
}
node_id = node.offset() ^ min_str[i];
@@ -151,32 +163,29 @@ void KeyCursor::ascending_init(const String &min_str, const String &max_str) {
}
return;
}
-
- node = trie_->ith_node(node_id);
- if (node.sibling() != INVALID_LABEL) {
- GRN_DAT_THROW_IF(MEMORY_ERROR,
- !buf_.push_back(node_id ^ min_str[i] ^ node.sibling()));
- }
}
- const Base base = trie_->ith_node(node_id).base();
- if (base.is_terminal()) {
+ node = trie_->ith_node(node_id);
+ if (node.is_terminal()) {
Key key;
- trie_->ith_key(base.key_id(), &key);
+ trie_->ith_key(node.key_id(), &key);
if ((key.length() != min_str.length()) ||
((flags_ & EXCEPT_LOWER_BOUND) != EXCEPT_LOWER_BOUND)) {
GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node_id));
+ } else if (node.sibling() != INVALID_LABEL) {
+ GRN_DAT_THROW_IF(MEMORY_ERROR,
+ !buf_.push_back(node_id ^ node.label() ^ node.sibling()));
}
return;
}
- UInt16 label = trie_->ith_node(node_id).child();
+ UInt16 label = node.child();
if ((label == TERMINAL_LABEL) &&
((flags_ & EXCEPT_LOWER_BOUND) == EXCEPT_LOWER_BOUND)) {
- label = trie_->ith_node(base.offset() ^ label).sibling();
+ label = trie_->ith_node(node.offset() ^ label).sibling();
}
if (label != INVALID_LABEL) {
- GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(base.offset() ^ label));
+ GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node.offset() ^ label));
}
}
@@ -189,6 +198,11 @@ void KeyCursor::descending_init(const String &min_str, const String &max_str) {
}
}
+ if ((max_str.ptr() == NULL) || (max_str.length() == 0)) {
+ GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(ROOT_NODE_ID));
+ return;
+ }
+
UInt32 node_id = ROOT_NODE_ID;
for (UInt32 i = 0; i < max_str.length(); ++i) {
const Base base = trie_->ith_node(node_id).base();
@@ -271,11 +285,6 @@ bool KeyCursor::ascending_next(Key *key) {
!buf_.push_back(node_id ^ node.label() ^ node.sibling()));
}
- if (node.child() != INVALID_LABEL) {
- GRN_DAT_THROW_IF(MEMORY_ERROR,
- !buf_.push_back(node.offset() ^ node.child()));
- }
-
if (node.is_terminal()) {
Key temp_key;
trie_->ith_key(node.key_id(), &temp_key);
@@ -291,6 +300,9 @@ bool KeyCursor::ascending_next(Key *key) {
*key = temp_key;
return true;
}
+ } else if (node.child() != INVALID_LABEL) {
+ GRN_DAT_THROW_IF(MEMORY_ERROR,
+ !buf_.push_back(node.offset() ^ node.child()));
}
}
return false;