null+****@clear*****
null+****@clear*****
2011年 7月 2日 (土) 14:19:25 JST
Susumu Yata 2011-07-02 05:19:25 +0000 (Sat, 02 Jul 2011) New Revision: 893c35296ff77e2eb43da21a0a3ef34564911cb5 Log: added grn::dat::String and changed cursors' interfaces. Added files: lib/dat/string.hpp Modified files: lib/dat.cpp lib/dat/Makefile.am lib/dat/common-prefix-cursor.cpp lib/dat/common-prefix-cursor.hpp lib/dat/cursor-factory.cpp lib/dat/cursor-factory.hpp lib/dat/cursor.hpp lib/dat/id-cursor.cpp lib/dat/id-cursor.hpp lib/dat/key-cursor.cpp lib/dat/key-cursor.hpp lib/dat/key.hpp lib/dat/memory-mapped-file-impl.cpp lib/dat/memory-mapped-file-impl.hpp lib/dat/memory-mapped-file.cpp lib/dat/memory-mapped-file.hpp lib/dat/predictive-cursor.cpp lib/dat/predictive-cursor.hpp lib/dat/vector.hpp Modified: lib/dat.cpp (+3 -3) =================================================================== --- lib/dat.cpp 2011-07-01 08:33:11 +0000 (445f777) +++ lib/dat.cpp 2011-07-02 05:19:25 +0000 (91cb51c) @@ -259,7 +259,7 @@ grn_dat_get_key2(grn_ctx *ctx, grn_dat *dat, grn_id id, grn_obj *bulk) grn::dat::Trie *trie = static_cast<grn::dat::Trie *>(dat->handle); trie->ith_key(id, &k); len = k.length(); - const char *key = k.ptr(); + const char *key = static_cast<const char *>(k.ptr()); if (bulk->header.impl_flags & GRN_OBJ_REFER) { bulk->u.b.head = (char *)key; bulk->u.b.curr = (char *)key + len; @@ -308,7 +308,7 @@ grn_dat_cursor_open(grn_ctx *ctx, grn_dat *dat, grn::dat::Trie *trie = static_cast<grn::dat::Trie *>(dat->handle); grn::dat::CommonPrefixCursor *cursor; cursor = new grn::dat::CommonPrefixCursor; - cursor->open(*trie, max, min_size, max_size, offset, limit); + cursor->open(*trie, grn::dat::String(max, max_size), min_size, offset, limit); dc->cursor = cursor; } else { /* todo: near */ @@ -423,7 +423,7 @@ _grn_dat_key(grn_ctx *ctx, grn_dat *dat, grn_id id, uint32_t *key_size) grn::dat::Trie *trie = static_cast<grn::dat::Trie *>(dat->handle); trie->ith_key(id, &k); *key_size = k.length(); - key = k.ptr(); + key = static_cast<const char *>(k.ptr()); } catch (const grn::dat::Exception &ex) { key = NULL; } Modified: lib/dat/Makefile.am (+1 -0) =================================================================== --- lib/dat/Makefile.am 2011-07-01 08:33:11 +0000 (93a1b85) +++ lib/dat/Makefile.am 2011-07-02 05:19:25 +0000 (8217637) @@ -30,6 +30,7 @@ noinst_HEADERS = \ memory-mapped-file.hpp \ node.hpp \ predictive-cursor.hpp \ + string.hpp \ timer.hpp \ trie.hpp \ usage.hpp \ Modified: lib/dat/common-prefix-cursor.cpp (+29 -32) =================================================================== --- lib/dat/common-prefix-cursor.cpp 2011-07-01 08:33:11 +0000 (2fb913b) +++ lib/dat/common-prefix-cursor.cpp 2011-07-02 05:19:25 +0000 (417b3a7) @@ -1,7 +1,6 @@ #include "common-prefix-cursor.hpp" #include <algorithm> -#include <cstring> #include "trie.hpp" @@ -20,18 +19,17 @@ CommonPrefixCursor::CommonPrefixCursor() CommonPrefixCursor::~CommonPrefixCursor() {} void CommonPrefixCursor::open(const Trie &trie, - const void *ptr, + const String &str, UInt32 min_length, - UInt32 max_length, UInt32 offset, UInt32 limit, UInt32 flags) { - GRN_DAT_THROW_IF(PARAM_ERROR, (ptr == NULL) && (max_length != 0)); - GRN_DAT_THROW_IF(PARAM_ERROR, min_length > max_length); + GRN_DAT_THROW_IF(PARAM_ERROR, (str.ptr() == NULL) && (str.length() != 0)); + GRN_DAT_THROW_IF(PARAM_ERROR, min_length > str.length()); flags = fix_flags(flags); CommonPrefixCursor new_cursor(trie, offset, limit, flags); - new_cursor.init(static_cast<const UInt8 *>(ptr), min_length, max_length); + new_cursor.init(str, min_length); new_cursor.swap(this); } @@ -52,6 +50,18 @@ bool CommonPrefixCursor::next(Key *key) { return true; } +CommonPrefixCursor::CommonPrefixCursor(const Trie &trie, + UInt32 offset, + UInt32 limit, + UInt32 flags) + : trie_(&trie), + offset_(offset), + limit_(limit), + flags_(flags), + buf_(), + cur_(0), + end_(0) {} + UInt32 CommonPrefixCursor::fix_flags(UInt32 flags) const { const UInt32 cursor_type = flags & CURSOR_TYPE_MASK; GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_type != 0) && @@ -72,35 +82,22 @@ UInt32 CommonPrefixCursor::fix_flags(UInt32 flags) const { return flags; } -CommonPrefixCursor::CommonPrefixCursor(const Trie &trie, - UInt32 offset, - UInt32 limit, - UInt32 flags) - : trie_(&trie), - offset_(offset), - limit_(limit), - flags_(flags), - buf_(), - cur_(0), - end_(0) {} - -void CommonPrefixCursor::init(const UInt8 *ptr, - UInt32 min_length, - UInt32 max_length) { - if ((limit_ == 0) || (offset_ > (max_length - min_length))) { +void CommonPrefixCursor::init(const String &str, + UInt32 min_length) { + if ((limit_ == 0) || (offset_ > (str.length() - min_length))) { return; } UInt32 node_id = ROOT_NODE_ID; UInt32 i; - for (i = 0; i < max_length; ++i) { + for (i = 0; i < str.length(); ++i) { const Base base = trie_->ith_node(node_id).base(); if (base.is_terminal()) { Key key; trie_->ith_key(base.key_id(), &key); - if ((key.length() >= min_length) && (key.length() <= max_length) && - (std::memcmp(ptr + i, key.ptr() + i, key.length() - i) == 0) && - ((key.length() < max_length) || + if ((key.length() >= min_length) && (key.length() <= str.length()) && + (str.substr(0, key.length()).compare(key.str(), i) == 0) && + ((key.length() < str.length()) || ((flags_ & EXCEPT_EXACT_MATCH) != EXCEPT_EXACT_MATCH))) { GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(key.id())); } @@ -114,26 +111,26 @@ void CommonPrefixCursor::init(const UInt8 *ptr, !buf_.push_back(trie_->ith_node(terminal).key_id())); } - node_id = base.offset() ^ ptr[i]; - if (trie_->ith_node(node_id).label() != ptr[i]) { + node_id = base.offset() ^ str[i]; + if (trie_->ith_node(node_id).label() != str[i]) { break; } } - if ((i == max_length) && + if ((i == str.length()) && (flags_ & EXCEPT_EXACT_MATCH) != EXCEPT_EXACT_MATCH) { const Base base = trie_->ith_node(node_id).base(); if (base.is_terminal()) { Key key; trie_->ith_key(base.key_id(), &key); - if ((key.length() >= min_length) && (key.length() <= max_length)) { + if ((key.length() >= min_length) && (key.length() <= str.length())) { GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(key.id())); } } else if (trie_->ith_node(node_id).child() == TERMINAL_LABEL) { const UInt32 terminal = base.offset() ^ TERMINAL_LABEL; Key key; trie_->ith_key(trie_->ith_node(terminal).key_id(), &key); - if ((key.length() >= min_length) && (key.length() <= max_length)) { + if ((key.length() >= min_length) && (key.length() <= str.length())) { GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(key.id())); } } @@ -162,5 +159,5 @@ void CommonPrefixCursor::swap(CommonPrefixCursor *cursor) { std::swap(end_, cursor->end_); } -} // namespace grn } // namespace dat +} // namespace grn Modified: lib/dat/common-prefix-cursor.hpp (+8 -8) =================================================================== --- lib/dat/common-prefix-cursor.hpp 2011-07-01 08:33:11 +0000 (27cd3da) +++ lib/dat/common-prefix-cursor.hpp 2011-07-02 05:19:25 +0000 (91acf13) @@ -1,5 +1,5 @@ -#ifndef GRN_DAT_COMMON_PREFIX_CURSOR_H -#define GRN_DAT_COMMON_PREFIX_CURSOR_H +#ifndef GRN_DAT_COMMON_PREFIX_CURSOR_HPP_ +#define GRN_DAT_COMMON_PREFIX_CURSOR_HPP_ #include "cursor.hpp" #include "vector.hpp" @@ -15,9 +15,8 @@ class CommonPrefixCursor : public Cursor { ~CommonPrefixCursor(); void open(const Trie &trie, - const void *ptr, + const String &str, UInt32 min_length, - UInt32 max_length, UInt32 offset = 0, UInt32 limit = UINT32_MAX, UInt32 flags = 0); @@ -46,10 +45,11 @@ class CommonPrefixCursor : public Cursor { UInt32 cur_; UInt32 end_; - UInt32 fix_flags(UInt32 flags) const; CommonPrefixCursor(const Trie &trie, UInt32 offset, UInt32 limit, UInt32 flags); - void init(const UInt8 *ptr, UInt32 min_length, UInt32 max_length); + + UInt32 fix_flags(UInt32 flags) const; + void init(const String &str, UInt32 min_length); void swap(CommonPrefixCursor *cursor); // Disallows copy and assignment. @@ -57,7 +57,7 @@ class CommonPrefixCursor : public Cursor { CommonPrefixCursor &operator=(const CommonPrefixCursor &); }; -} // namespace grn } // namespace dat +} // namespace grn -#endif // GRN_DAT_COMMON_PREFIX_CURSOR_H +#endif // GRN_DAT_COMMON_PREFIX_CURSOR_HPP_ Modified: lib/dat/cursor-factory.cpp (+7 -7) =================================================================== --- lib/dat/cursor-factory.cpp 2011-07-01 08:33:11 +0000 (a89f3a0) +++ lib/dat/cursor-factory.cpp 2011-07-02 05:19:25 +0000 (1bcb5e2) @@ -21,8 +21,8 @@ Cursor *CursorFactory::open(const Trie &trie, IdCursor *cursor = new (std::nothrow) IdCursor; GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL); try { - cursor->open(trie, min_ptr, min_length, max_ptr, max_length, - offset, limit, flags); + cursor->open(trie, String(min_ptr, min_length), + String(max_ptr, max_length), offset, limit, flags); } catch (...) { delete cursor; throw; @@ -33,8 +33,8 @@ Cursor *CursorFactory::open(const Trie &trie, KeyCursor *cursor = new (std::nothrow) KeyCursor; GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL); try { - cursor->open(trie, min_ptr, min_length, max_ptr, max_length, - offset, limit, flags); + cursor->open(trie, String(min_ptr, min_length), + String(max_ptr, max_length), offset, limit, flags); } catch (...) { delete cursor; throw; @@ -45,7 +45,7 @@ Cursor *CursorFactory::open(const Trie &trie, CommonPrefixCursor *cursor = new (std::nothrow) CommonPrefixCursor; GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL); try { - cursor->open(trie, max_ptr, min_length, max_length, + cursor->open(trie, String(max_ptr, max_length), min_length, offset, limit, flags); } catch (...) { delete cursor; @@ -57,7 +57,7 @@ Cursor *CursorFactory::open(const Trie &trie, PredictiveCursor *cursor = new (std::nothrow) PredictiveCursor; GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL); try { - cursor->open(trie, min_ptr, min_length, + cursor->open(trie, String(min_ptr, min_length), offset, limit, flags); } catch (...) { delete cursor; @@ -71,5 +71,5 @@ Cursor *CursorFactory::open(const Trie &trie, } } -} // namespace grn } // namespace dat +} // namespace grn Modified: lib/dat/cursor-factory.hpp (+4 -4) =================================================================== --- lib/dat/cursor-factory.hpp 2011-07-01 08:33:11 +0000 (6db5012) +++ lib/dat/cursor-factory.hpp 2011-07-02 05:19:25 +0000 (d50a1cc) @@ -1,5 +1,5 @@ -#ifndef GRN_DAT_CURSOR_FACTORY_H -#define GRN_DAT_CURSOR_FACTORY_H +#ifndef GRN_DAT_CURSOR_FACTORY_HPP_ +#define GRN_DAT_CURSOR_FACTORY_HPP_ #include "cursor.hpp" @@ -23,7 +23,7 @@ class CursorFactory { CursorFactory &operator=(const CursorFactory &); }; -} // namespace grn } // namespace dat +} // namespace grn -#endif // GRN_DAT_CURSOR_FACTORY_H +#endif // GRN_DAT_CURSOR_FACTORY_HPP_ Modified: lib/dat/cursor.hpp (+4 -4) =================================================================== --- lib/dat/cursor.hpp 2011-07-01 08:33:11 +0000 (ae11dc2) +++ lib/dat/cursor.hpp 2011-07-02 05:19:25 +0000 (ae5e428) @@ -1,5 +1,5 @@ -#ifndef GRN_DAT_CURSOR_H -#define GRN_DAT_CURSOR_H +#ifndef GRN_DAT_CURSOR_HPP_ +#define GRN_DAT_CURSOR_HPP_ #include "key.hpp" @@ -25,7 +25,7 @@ class Cursor { Cursor &operator=(const Cursor &); }; -} // namespace grn } // namespace dat +} // namespace grn -#endif // GRN_DAT_CURSOR_H +#endif // GRN_DAT_CURSOR_HPP_ Modified: lib/dat/id-cursor.cpp (+18 -19) =================================================================== --- lib/dat/id-cursor.cpp 2011-07-01 08:33:11 +0000 (312602b) +++ lib/dat/id-cursor.cpp 2011-07-02 05:19:25 +0000 (67e620b) @@ -18,25 +18,24 @@ IdCursor::IdCursor() IdCursor::~IdCursor() {} void IdCursor::open(const Trie &trie, - const void *min_ptr, UInt32 min_length, - const void *max_ptr, UInt32 max_length, + const String &min_str, + const String &max_str, UInt32 offset, UInt32 limit, UInt32 flags) { - GRN_DAT_THROW_IF(PARAM_ERROR, (min_ptr == NULL) && (min_length != 0)); - GRN_DAT_THROW_IF(PARAM_ERROR, (max_ptr == NULL) && (max_length != 0)); - UInt32 min_id = INVALID_KEY_ID; - if (min_ptr != NULL) { + if (min_str.ptr() != NULL) { Key key; - GRN_DAT_THROW_IF(PARAM_ERROR, !trie.search(min_ptr, min_length, &key)); + GRN_DAT_THROW_IF(PARAM_ERROR, + !trie.search(min_str.ptr(), min_str.length(), &key)); min_id = key.id(); } UInt32 max_id = INVALID_KEY_ID; - if (max_ptr != NULL) { + if (max_str.ptr() != NULL) { Key key; - GRN_DAT_THROW_IF(PARAM_ERROR, !trie.search(max_ptr, max_length, &key)); + GRN_DAT_THROW_IF(PARAM_ERROR, + !trie.search(max_str.ptr(), max_str.length(), &key)); max_id = key.id(); } @@ -74,6 +73,15 @@ bool IdCursor::next(Key *key) { return true; } +IdCursor::IdCursor(const Trie &trie, + UInt32 offset, UInt32 limit, UInt32 flags) + : trie_(&trie), + offset_(offset), + limit_(limit), + flags_(flags), + cur_(INVALID_KEY_ID), + end_(INVALID_KEY_ID) {} + UInt32 IdCursor::fix_flags(UInt32 flags) const { const UInt32 cursor_type = flags & CURSOR_TYPE_MASK; GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_type != 0) && @@ -95,15 +103,6 @@ UInt32 IdCursor::fix_flags(UInt32 flags) const { return flags; } -IdCursor::IdCursor(const Trie &trie, - UInt32 offset, UInt32 limit, UInt32 flags) - : trie_(&trie), - offset_(offset), - limit_(limit), - flags_(flags), - cur_(INVALID_KEY_ID), - end_(INVALID_KEY_ID) {} - void IdCursor::init(UInt32 min_id, UInt32 max_id) { if (min_id == INVALID_KEY_ID) { min_id = trie_->min_key_id(); @@ -154,5 +153,5 @@ void IdCursor::swap(IdCursor *cursor) { std::swap(end_, cursor->end_); } -} // namespace grn } // namespace dat +} // namespace grn Modified: lib/dat/id-cursor.hpp (+8 -7) =================================================================== --- lib/dat/id-cursor.hpp 2011-07-01 08:33:11 +0000 (83a4b1d) +++ lib/dat/id-cursor.hpp 2011-07-02 05:19:25 +0000 (fe836d8) @@ -1,5 +1,5 @@ -#ifndef GRN_DAT_ID_CURSOR_H -#define GRN_DAT_ID_CURSOR_H +#ifndef GRN_DAT_ID_CURSOR_HPP_ +#define GRN_DAT_ID_CURSOR_HPP_ #include "cursor.hpp" @@ -14,8 +14,8 @@ class IdCursor : public Cursor { ~IdCursor(); void open(const Trie &trie, - const void *min_ptr, UInt32 min_length, - const void *max_ptr, UInt32 max_length, + const String &min_str, + const String &max_str, UInt32 offset = 0, UInt32 limit = UINT32_MAX, UInt32 flags = 0); @@ -50,8 +50,9 @@ class IdCursor : public Cursor { UInt32 cur_; UInt32 end_; - UInt32 fix_flags(UInt32 flags) const; IdCursor(const Trie &trie, UInt32 offset, UInt32 limit, UInt32 flags); + + UInt32 fix_flags(UInt32 flags) const; void init(UInt32 min_id, UInt32 max_id); void swap(IdCursor *cursor); @@ -60,7 +61,7 @@ class IdCursor : public Cursor { IdCursor &operator=(const IdCursor &); }; -} // namespace grn } // namespace dat +} // namespace grn -#endif // GRN_DAT_ID_CURSOR_H +#endif // GRN_DAT_ID_CURSOR_HPP_ Modified: lib/dat/key-cursor.cpp (+64 -84) =================================================================== --- lib/dat/key-cursor.cpp 2011-07-01 08:33:11 +0000 (75e52b2) +++ lib/dat/key-cursor.cpp 2011-07-02 05:19:25 +0000 (fac4e34) @@ -16,29 +16,30 @@ KeyCursor::KeyCursor() buf_(), count_(0), max_count_(0), - end_(false), - end_ptr_(NULL), - end_length_(0) {} + finished_(false), + end_buf_(NULL), + end_str_() {} KeyCursor::~KeyCursor() { - if ((end_ptr_ != NULL) && (end_length_ != 0)) { - delete [] end_ptr_; + if (end_buf_ != NULL) { + delete [] end_buf_; } } void KeyCursor::open(const Trie &trie, - const void *min_ptr, UInt32 min_length, - const void *max_ptr, UInt32 max_length, + const String &min_str, + const String &max_str, UInt32 offset, UInt32 limit, UInt32 flags) { - GRN_DAT_THROW_IF(PARAM_ERROR, (min_ptr == NULL) && (min_length != 0)); - GRN_DAT_THROW_IF(PARAM_ERROR, (max_ptr == NULL) && (max_length != 0)); + GRN_DAT_THROW_IF(PARAM_ERROR, + (min_str.ptr() == NULL) && (min_str.length() != 0)); + GRN_DAT_THROW_IF(PARAM_ERROR, + (max_str.ptr() == NULL) && (max_str.length() != 0)); flags = fix_flags(flags); KeyCursor new_cursor(trie, offset, limit, flags); - new_cursor.init(static_cast<const UInt8 *>(min_ptr), min_length, - static_cast<const UInt8 *>(max_ptr), max_length); + new_cursor.init(min_str, max_str); new_cursor.swap(this); } @@ -48,7 +49,7 @@ void KeyCursor::close() { } bool KeyCursor::next(Key *key) { - if (end_ || (count_ >= max_count_)) { + if (finished_ || (count_ >= max_count_)) { return false; } @@ -59,6 +60,19 @@ bool KeyCursor::next(Key *key) { } } +KeyCursor::KeyCursor(const Trie &trie, + UInt32 offset, UInt32 limit, UInt32 flags) + : trie_(&trie), + offset_(offset), + limit_(limit), + flags_(flags), + buf_(), + count_(0), + max_count_(0), + finished_(false), + end_buf_(NULL), + end_str_() {} + UInt32 KeyCursor::fix_flags(UInt32 flags) const { const UInt32 cursor_type = flags & CURSOR_TYPE_MASK; GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_type != 0) && @@ -80,21 +94,7 @@ UInt32 KeyCursor::fix_flags(UInt32 flags) const { return flags; } -KeyCursor::KeyCursor(const Trie &trie, - UInt32 offset, UInt32 limit, UInt32 flags) - : trie_(&trie), - offset_(offset), - limit_(limit), - flags_(flags), - buf_(), - count_(0), - max_count_(0), - end_(false), - end_ptr_(NULL), - end_length_(0) {} - -void KeyCursor::init(const UInt8 *min_ptr, UInt32 min_length, - const UInt8 *max_ptr, UInt32 max_length) { +void KeyCursor::init(const String &min_str, const String &max_str) { if (offset_ > (UINT32_MAX - limit_)) { max_count_ = UINT32_MAX; } else { @@ -106,31 +106,28 @@ void KeyCursor::init(const UInt8 *min_ptr, UInt32 min_length, } if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) { - ascending_init(min_ptr, min_length, max_ptr, max_length); + ascending_init(min_str, max_str); } else { - descending_init(min_ptr, min_length, max_ptr, max_length); + descending_init(min_str, max_str); } } -void KeyCursor::ascending_init(const UInt8 *min_ptr, UInt32 min_length, - const UInt8 *max_ptr, UInt32 max_length) { - if (max_ptr != NULL) { - if (max_length != 0) { - end_ptr_ = new UInt8[max_length]; - std::memcpy(end_ptr_, max_ptr, max_length); - } else { - end_ptr_ = reinterpret_cast<UInt8 *>(const_cast<char *>("")); +void KeyCursor::ascending_init(const String &min_str, const String &max_str) { + if (max_str.ptr() != NULL) { + if (max_str.length() != 0) { + end_buf_ = new UInt8[max_str.length()]; + std::memcpy(end_buf_, max_str.ptr(), max_str.length()); + end_str_.assign(end_buf_, max_str.length()); } } - end_length_ = max_length; UInt32 node_id = ROOT_NODE_ID; Node node = trie_->ith_node(node_id); - for (UInt32 i = 0; i < min_length; ++i) { + for (UInt32 i = 0; i < min_str.length(); ++i) { if (node.is_terminal()) { Key key; trie_->ith_key(node.key_id(), &key); - const int result = compare(key, min_ptr, min_length, i); + const int result = key.str().compare(min_str, i); if ((result > 0) || ((result == 0) && ((flags_ & EXCEPT_LOWER_BOUND) != EXCEPT_LOWER_BOUND))) { GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node_id)); @@ -138,14 +135,14 @@ void KeyCursor::ascending_init(const UInt8 *min_ptr, UInt32 min_length, return; } - node_id = node.offset() ^ min_ptr[i]; - if (trie_->ith_node(node_id).label() != min_ptr[i]) { + node_id = node.offset() ^ min_str[i]; + if (trie_->ith_node(node_id).label() != min_str[i]) { UInt16 label = node.child(); if (label == TERMINAL_LABEL) { label = trie_->ith_node(node.offset() ^ label).sibling(); } while (label != INVALID_LABEL) { - if (label > min_ptr[i]) { + if (label > min_str[i]) { GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node.offset() ^ label)); break; @@ -158,7 +155,7 @@ void KeyCursor::ascending_init(const UInt8 *min_ptr, UInt32 min_length, node = trie_->ith_node(node_id); if (node.sibling() != INVALID_LABEL) { GRN_DAT_THROW_IF(MEMORY_ERROR, - !buf_.push_back(node_id ^ min_ptr[i] ^ node.sibling())); + !buf_.push_back(node_id ^ min_str[i] ^ node.sibling())); } } @@ -166,7 +163,7 @@ void KeyCursor::ascending_init(const UInt8 *min_ptr, UInt32 min_length, if (base.is_terminal()) { Key key; trie_->ith_key(base.key_id(), &key); - if ((key.length() != min_length) || + if ((key.length() != min_str.length()) || ((flags_ & EXCEPT_LOWER_BOUND) != EXCEPT_LOWER_BOUND)) { GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node_id)); } @@ -183,25 +180,22 @@ void KeyCursor::ascending_init(const UInt8 *min_ptr, UInt32 min_length, } } -void KeyCursor::descending_init(const UInt8 *min_ptr, UInt32 min_length, - const UInt8 *max_ptr, UInt32 max_length) { - if (min_ptr != NULL) { - if (min_length != 0) { - end_ptr_ = new UInt8[min_length]; - std::memcpy(end_ptr_, min_ptr, min_length); - } else { - end_ptr_ = reinterpret_cast<UInt8 *>(const_cast<char *>("")); +void KeyCursor::descending_init(const String &min_str, const String &max_str) { + if (min_str.ptr() != NULL) { + if (min_str.length() != 0) { + end_buf_ = new UInt8[min_str.length()]; + std::memcpy(end_buf_, min_str.ptr(), min_str.length()); + end_str_.assign(end_buf_, min_str.length()); } } - end_length_ = min_length; UInt32 node_id = ROOT_NODE_ID; - for (UInt32 i = 0; i < max_length; ++i) { + for (UInt32 i = 0; i < max_str.length(); ++i) { const Base base = trie_->ith_node(node_id).base(); if (base.is_terminal()) { Key key; trie_->ith_key(base.key_id(), &key); - const int result = compare(key, max_ptr, max_length, i); + const int result = key.str().compare(max_str, i); if ((result < 0) || ((result == 0) && ((flags_ & EXCEPT_UPPER_BOUND) != EXCEPT_UPPER_BOUND))) { GRN_DAT_THROW_IF(MEMORY_ERROR, @@ -219,9 +213,9 @@ void KeyCursor::descending_init(const UInt8 *min_ptr, UInt32 min_length, } while (label != INVALID_LABEL) { node_id = base.offset() ^ label; - if (label < max_ptr[i]) { + if (label < max_str[i]) { GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node_id)); - } else if (label > max_ptr[i]) { + } else if (label > max_str[i]) { return; } else { break; @@ -237,7 +231,7 @@ void KeyCursor::descending_init(const UInt8 *min_ptr, UInt32 min_length, if (base.is_terminal()) { Key key; trie_->ith_key(base.key_id(), &key); - if ((key.length() == max_length) && + if ((key.length() == max_str.length()) && ((flags_ & EXCEPT_UPPER_BOUND) != EXCEPT_UPPER_BOUND)) { GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node_id | POST_ORDER_FLAG)); @@ -261,9 +255,9 @@ void KeyCursor::swap(KeyCursor *cursor) { buf_.swap(&cursor->buf_); std::swap(count_, cursor->count_); std::swap(max_count_, cursor->max_count_); - std::swap(end_, cursor->end_); - std::swap(end_ptr_, cursor->end_ptr_); - std::swap(end_length_, cursor->end_length_); + std::swap(finished_, cursor->finished_); + std::swap(end_buf_, cursor->end_buf_); + end_str_.swap(&cursor->end_str_); } bool KeyCursor::ascending_next(Key *key) { @@ -285,11 +279,11 @@ bool KeyCursor::ascending_next(Key *key) { if (node.is_terminal()) { Key temp_key; trie_->ith_key(node.key_id(), &temp_key); - if (end_ptr_ != NULL) { - const int result = compare(temp_key, end_ptr_, end_length_, 0); + if (end_buf_ != NULL) { + const int result = temp_key.str().compare(end_str_); if ((result > 0) || ((result == 0) && ((flags_ & EXCEPT_UPPER_BOUND) == EXCEPT_UPPER_BOUND))) { - end_ = true; + finished_ = true; return false; } } @@ -313,11 +307,12 @@ bool KeyCursor::descending_next(Key *key) { if (base.is_terminal()) { Key temp_key; trie_->ith_key(base.key_id(), &temp_key); - if (end_ptr_ != NULL) { - const int result = compare(temp_key, end_ptr_, end_length_, 0); + if (end_buf_ != NULL) { + const int result = + temp_key.str().compare(end_str_); if ((result < 0) || ((result == 0) && ((flags_ & EXCEPT_LOWER_BOUND) == EXCEPT_LOWER_BOUND))) { - end_ = true; + finished_ = true; return false; } } @@ -338,20 +333,5 @@ bool KeyCursor::descending_next(Key *key) { return false; } -int KeyCursor::compare(const Key &key, - const UInt8 *ptr, UInt32 length, - UInt32 offset) const { - const UInt32 min_length = (key.length() < length) ? key.length() : length; - for (UInt32 i = offset; i < min_length; ++i) { - if (static_cast<UInt8>(key[i]) != ptr[i]) { - return static_cast<UInt8>(key[i]) - ptr[i]; - } - } - if (key.length() < length) { - return -1; - } - return (key.length() > length) ? 1 : 0; -} - -} // namespace grn } // namespace dat +} // namespace grn Modified: lib/dat/key-cursor.hpp (+12 -18) =================================================================== --- lib/dat/key-cursor.hpp 2011-07-01 08:33:11 +0000 (4825a63) +++ lib/dat/key-cursor.hpp 2011-07-02 05:19:25 +0000 (34c8f21) @@ -15,8 +15,8 @@ class KeyCursor : public Cursor { ~KeyCursor(); void open(const Trie &trie, - const void *min_ptr, UInt32 min_length, - const void *max_ptr, UInt32 max_length, + const String &min_str, + const String &max_str, UInt32 offset = 0, UInt32 limit = UINT32_MAX, UInt32 flags = 0); @@ -44,28 +44,22 @@ class KeyCursor : public Cursor { Vector<UInt32> buf_; UInt32 count_; UInt32 max_count_; - bool end_; - UInt8 *end_ptr_; - UInt32 end_length_; + bool finished_; + UInt8 *end_buf_; + String end_str_; - UInt32 fix_flags(UInt32 flags) const; KeyCursor(const Trie &trie, - UInt32 offset, UInt32 limit, UInt32 flags); - void init(const UInt8 *min_ptr, UInt32 min_length, - const UInt8 *max_ptr, UInt32 max_length); - void ascending_init(const UInt8 *min_ptr, UInt32 min_length, - const UInt8 *max_ptr, UInt32 max_length); - void descending_init(const UInt8 *min_ptr, UInt32 min_length, - const UInt8 *max_ptr, UInt32 max_length); + UInt32 offset, UInt32 limit, UInt32 flags); + + UInt32 fix_flags(UInt32 flags) const; + void init(const String &min_str, const String &max_str); + void ascending_init(const String &min_str, const String &max_str); + void descending_init(const String &min_str, const String &max_str); void swap(KeyCursor *cursor); bool ascending_next(Key *key); bool descending_next(Key *key); - int compare(const Key &key, - const UInt8 *ptr, UInt32 length, - UInt32 offset) const; - static const UInt32 POST_ORDER_FLAG = 0x80000000U; // Disallows copy and assignment. @@ -73,7 +67,7 @@ class KeyCursor : public Cursor { KeyCursor &operator=(const KeyCursor &); }; -} // namespace grn } // namespace dat +} // namespace grn #endif // GRN_DAT_KEY_CURSOR_HPP_ Modified: lib/dat/key.hpp (+21 -12) =================================================================== --- lib/dat/key.hpp 2011-07-01 08:33:11 +0000 (a0c5c10) +++ lib/dat/key.hpp 2011-07-02 05:19:25 +0000 (ab0927a) @@ -1,41 +1,50 @@ #ifndef GRN_DAT_KEY_HPP_ #define GRN_DAT_KEY_HPP_ -#include "dat.hpp" +#include "string.hpp" namespace grn { namespace dat { class Key { public: - const char &operator[](UInt32 i) const { - GRN_DAT_DEBUG_THROW_IF(i > length_); - return ptr_[i]; + Key() + : str_(), + id_(INVALID_KEY_ID) {} + + const UInt8 &operator[](UInt32 i) const { + GRN_DAT_DEBUG_THROW_IF(i >= str_.length()); + return str_[i]; } - const char *ptr() const { - return ptr_; + const String &str() const { + return str_; + } + const void *ptr() const { + return str_.ptr(); } UInt32 length() const { - return length_; + return str_.length(); } UInt32 id() const { return id_; } - void set_ptr(const char *x) { - ptr_ = x; + void set_str(const void *ptr, UInt32 length) { + str_.assign(ptr, length); + } + void set_ptr(const void *x) { + str_.set_ptr(x); } void set_length(UInt32 x) { - length_ = x; + str_.set_length(x); } void set_id(UInt32 x) { id_ = x; } private: - const char *ptr_; - UInt32 length_; + String str_; UInt32 id_; }; Modified: lib/dat/memory-mapped-file-impl.cpp (+1 -1) =================================================================== --- lib/dat/memory-mapped-file-impl.cpp 2011-07-01 08:33:11 +0000 (a80c596) +++ lib/dat/memory-mapped-file-impl.cpp 2011-07-02 05:19:25 +0000 (5646bef) @@ -212,5 +212,5 @@ void MemoryMappedFileImpl::open_(const char *path) { #endif // WIN32 -} // namespace grn } // namespace dat +} // namespace grn Modified: lib/dat/memory-mapped-file-impl.hpp (+1 -1) =================================================================== --- lib/dat/memory-mapped-file-impl.hpp 2011-07-01 08:33:11 +0000 (aa6cf0c) +++ lib/dat/memory-mapped-file-impl.hpp 2011-07-02 05:19:25 +0000 (66164ff) @@ -50,7 +50,7 @@ class MemoryMappedFileImpl { MemoryMappedFileImpl &operator=(const MemoryMappedFileImpl &); }; -} // namespace grn } // namespace dat +} // namespace grn #endif // GRN_DAT_MEMORY_MAPPED_FILE_IMPL_HPP_ Modified: lib/dat/memory-mapped-file.cpp (+1 -1) =================================================================== --- lib/dat/memory-mapped-file.cpp 2011-07-01 08:33:11 +0000 (9c76ef5) +++ lib/dat/memory-mapped-file.cpp 2011-07-02 05:19:25 +0000 (973bb17) @@ -58,5 +58,5 @@ void MemoryMappedFile::swap(MemoryMappedFile *rhs) { rhs->impl_ = temp; } -} // namespace grn } // namespace dat +} // namespace grn Modified: lib/dat/memory-mapped-file.hpp (+1 -1) =================================================================== --- lib/dat/memory-mapped-file.hpp 2011-07-01 08:33:11 +0000 (7d85f6b) +++ lib/dat/memory-mapped-file.hpp 2011-07-02 05:19:25 +0000 (4baedc2) @@ -30,7 +30,7 @@ class MemoryMappedFile { MemoryMappedFile &operator=(const MemoryMappedFile &); }; -} // namespace grn } // namespace dat +} // namespace grn #endif // GRN_DAT_MEMORY_MAPPED_FILE_HPP_ Modified: lib/dat/predictive-cursor.cpp (+22 -25) =================================================================== --- lib/dat/predictive-cursor.cpp 2011-07-01 08:33:11 +0000 (58d31c3) +++ lib/dat/predictive-cursor.cpp 2011-07-02 05:19:25 +0000 (f5e755f) @@ -21,16 +21,15 @@ PredictiveCursor::PredictiveCursor() PredictiveCursor::~PredictiveCursor() {} void PredictiveCursor::open(const Trie &trie, - const void *ptr, - UInt32 length, + const String &str, UInt32 offset, UInt32 limit, UInt32 flags) { - GRN_DAT_THROW_IF(PARAM_ERROR, (ptr == NULL) && (length != 0)); + GRN_DAT_THROW_IF(PARAM_ERROR, (str.ptr() == NULL) && (str.length() != 0)); flags = fix_flags(flags); PredictiveCursor new_cursor(trie, offset, limit, flags); - new_cursor.init(static_cast<const UInt8 *>(ptr), length); + new_cursor.init(str); new_cursor.swap(this); } @@ -51,6 +50,17 @@ bool PredictiveCursor::next(Key *key) { } } +PredictiveCursor::PredictiveCursor(const Trie &trie, + UInt32 offset, UInt32 limit, UInt32 flags) + : trie_(&trie), + offset_(offset), + limit_(limit), + flags_(flags), + buf_(), + cur_(0), + end_(0), + min_length_(0) {} + UInt32 PredictiveCursor::fix_flags(UInt32 flags) const { const UInt32 cursor_type = flags & CURSOR_TYPE_MASK; GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_type != 0) && @@ -71,47 +81,34 @@ UInt32 PredictiveCursor::fix_flags(UInt32 flags) const { return flags; } -PredictiveCursor::PredictiveCursor(const Trie &trie, - UInt32 offset, - UInt32 limit, - UInt32 flags) - : trie_(&trie), - offset_(offset), - limit_(limit), - flags_(flags), - buf_(), - cur_(0), - end_(0), - min_length_(0) {} - -void PredictiveCursor::init(const UInt8 *ptr, UInt32 length) { +void PredictiveCursor::init(const String &str) { if (limit_ == 0) { return; } - min_length_ = length; + min_length_ = str.length(); if ((flags_ & EXCEPT_EXACT_MATCH) == EXCEPT_EXACT_MATCH) { ++min_length_; } end_ = (offset_ > (UINT32_MAX - limit_)) ? UINT32_MAX : (offset_ + limit_); UInt32 node_id = ROOT_NODE_ID; - for (UInt32 i = 0; i < length; ++i) { + for (UInt32 i = 0; i < str.length(); ++i) { const Base base = trie_->ith_node(node_id).base(); if (base.is_terminal()) { if (offset_ == 0) { Key key; trie_->ith_key(base.key_id(), &key); - if ((key.length() >= length) && - (std::memcmp(ptr + i, key.ptr() + i, length - i) == 0)) { + if ((key.length() >= str.length()) && + (key.str().substr(0, str.length()).compare(str, i) == 0)) { GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node_id)); } } return; } - node_id = base.offset() ^ ptr[i]; - if (trie_->ith_node(node_id).label() != ptr[i]) { + node_id = base.offset() ^ str[i]; + if (trie_->ith_node(node_id).label() != str[i]) { return; } } @@ -187,5 +184,5 @@ bool PredictiveCursor::descending_next(Key *key) { return false; } -} // namespace grn } // namespace dat +} // namespace grn Modified: lib/dat/predictive-cursor.hpp (+5 -5) =================================================================== --- lib/dat/predictive-cursor.hpp 2011-07-01 08:33:11 +0000 (2caa671) +++ lib/dat/predictive-cursor.hpp 2011-07-02 05:19:25 +0000 (fa3e7b4) @@ -15,8 +15,7 @@ class PredictiveCursor : public Cursor { ~PredictiveCursor(); void open(const Trie &trie, - const void *ptr, - UInt32 length, + const String &str, UInt32 offset = 0, UInt32 limit = UINT32_MAX, UInt32 flags = 0); @@ -46,10 +45,11 @@ class PredictiveCursor : public Cursor { UInt32 end_; UInt32 min_length_; - UInt32 fix_flags(UInt32 flags) const; PredictiveCursor(const Trie &trie, UInt32 offset, UInt32 limit, UInt32 flags); - void init(const UInt8 *ptr, UInt32 length); + + UInt32 fix_flags(UInt32 flags) const; + void init(const String &str); void swap(PredictiveCursor *cursor); bool ascending_next(Key *key); @@ -62,7 +62,7 @@ class PredictiveCursor : public Cursor { PredictiveCursor &operator=(const PredictiveCursor &); }; -} // namespace grn } // namespace dat +} // namespace grn #endif // GRN_DAT_PREDICTIVE_CURSOR_HPP_ Added: lib/dat/string.hpp (+155 -0) 100644 =================================================================== --- /dev/null +++ lib/dat/string.hpp 2011-07-02 05:19:25 +0000 (bd137fa) @@ -0,0 +1,155 @@ +#ifndef GRN_DAT_STRING_HPP_ +#define GRN_DAT_STRING_HPP_ + +#include "dat.hpp" + +namespace grn { +namespace dat { + +class String { + public: + String() + : ptr_(NULL), + length_(0) {} + String(const void *ptr, UInt32 length) + : ptr_(static_cast<const UInt8 *>(ptr)), + length_(length) {} + String(const String &rhs) + : ptr_(rhs.ptr_), + length_(rhs.length_) {} + + String &operator=(const String &rhs) { + set_ptr(rhs.ptr()); + set_length(rhs.length()); + return *this; + } + + const UInt8 &operator[](UInt32 i) const { + GRN_DAT_DEBUG_THROW_IF(i >= length_); + return ptr_[i]; + } + + const void *ptr() const { + return ptr_; + } + UInt32 length() const { + return length_; + } + + void set_ptr(const void *x) { + ptr_ = static_cast<const UInt8 *>(x); + } + void set_length(UInt32 x) { + length_ = x; + } + + void assign(const void *ptr, UInt32 length) { + set_ptr(ptr); + set_length(length); + } + + String substr(UInt32 offset = 0) const { + return String(ptr_ + offset, length_ - offset); + } + String substr(UInt32 offset, UInt32 length) const { + return String(ptr_ + offset, length); + } + + // This function returns an integer as follows: + // - a negative value if *this < rhs, + // - zero if *this == rhs, + // - a positive value if *this > rhs, + // but if the offset is too large, the result is undefined. + int compare(const String &rhs, UInt32 offset = 0) const { + GRN_DAT_DEBUG_THROW_IF(offset > length()); + GRN_DAT_DEBUG_THROW_IF(offset > rhs.length()); + + UInt32 i; + for (i = offset; i < length(); ++i) { + if (i >= rhs.length()) { + return 1; + } else if ((*this)[i] != rhs[i]) { + return (*this)[i] - rhs[i]; + } + } + return (i == rhs.length()) ? 0 : -1; + } + + bool starts_with(const String &str) const { + if (length() < str.length()) { + return false; + } + for (UInt32 i = 0; i < str.length(); ++i) { + if ((*this)[i] != str[i]) { + return false; + } + } + return true; + } + + bool ends_with(const String &str) const { + if (length() < str.length()) { + return false; + } + UInt32 offset = length() - str.length(); + for (UInt32 i = 0; i < str.length(); ++i) { + if ((*this)[offset + i] != str[i]) { + return false; + } + } + return true; + } + + void swap(String *rhs) { + const UInt8 * const ptr_temp = ptr_; + ptr_ = rhs->ptr_; + rhs->ptr_ = ptr_temp; + + const UInt32 length_temp = length_; + length_ = rhs->length_; + rhs->length_ = length_temp; + } + + private: + const UInt8 *ptr_; + UInt32 length_; +}; + +inline bool operator==(const String &lhs, const String &rhs) { + if (lhs.length() != rhs.length()) { + return false; + } else if (lhs.ptr() == rhs.ptr()) { + return true; + } + for (UInt32 i = 0; i < lhs.length(); ++i) { + if (lhs[i] != rhs[i]) { + return false; + } + } + return true; +} + +inline bool operator!=(const String &lhs, const String &rhs) { + return !(lhs == rhs); +} + +inline bool operator<(const String &lhs, const String &rhs) { + return lhs.compare(rhs) < 0; +} + +inline bool operator>(const String &lhs, const String &rhs) { + return rhs < lhs; +} + +inline bool operator<=(const String &lhs, const String &rhs) { + return !(lhs > rhs); +} + +inline bool operator>=(const String &lhs, const String &rhs) { + return !(lhs < rhs); +} + +} // namespace dat +} // namespace grn + +#endif // GRN_DAT_STRING_HPP_ Modified: lib/dat/vector.hpp (+1 -1) =================================================================== --- lib/dat/vector.hpp 2011-07-01 08:33:11 +0000 (e77a932) +++ lib/dat/vector.hpp 2011-07-02 05:19:25 +0000 (8f9f1d3) @@ -60,7 +60,7 @@ class Vector { Vector &operator=(const Vector &); }; -} // namespace grn } // namespace dat +} // namespace grn #endif // GRN_DAT_VECTOR_HPP_