コード例 #1
0
ファイル: predictive-cursor.cpp プロジェクト: temita/groonga
bool PredictiveCursor::ascending_next(Key *key) {
  while (!buf_.empty()) {
    const bool is_root = (buf_.back() & IS_ROOT_FLAG) == IS_ROOT_FLAG;
    const UInt32 node_id = buf_.back() & ~IS_ROOT_FLAG;
    buf_.pop_back();

    const Node node = trie_->ith_node(node_id);
    if (!is_root && (node.sibling() != INVALID_LABEL)) {
      GRN_DAT_THROW_IF(MEMORY_ERROR,
          !buf_.push_back(node_id ^ node.label() ^ node.sibling()));
    }

    if (node.is_terminal()) {
      Key temp_key;
      trie_->ith_key(node.key_id(), &temp_key);
      if (temp_key.length() >= min_length_) {
        if (cur_++ >= offset_) {
          *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;
}
コード例 #2
0
ファイル: vector.hpp プロジェクト: XLPE/groonga
  void reserve(UInt32 new_capacity) {
    if (new_capacity <= capacity()) {
      return;
    } else if ((new_capacity / 2) < capacity()) {
      if (capacity() < (MAX_UINT32 / 2)) {
        new_capacity = capacity() * 2;
      } else {
        new_capacity = MAX_UINT32;
      }
    }

    T *new_buf = reinterpret_cast<T *>(
        new (std::nothrow) char[sizeof(new_capacity) * new_capacity]);
    GRN_DAT_THROW_IF(MEMORY_ERROR, new_buf == NULL);

    for (UInt32 i = 0; i < size(); ++i) {
      new (&new_buf[i]) T(buf_[i]);
    }
    for (UInt32 i = 0; i < size(); ++i) {
      buf_[i].~T();
    }

    T *old_buf = buf_;
    buf_ = new_buf;
    delete [] reinterpret_cast<char *>(old_buf);

    capacity_ = new_capacity;
  }
コード例 #3
0
ファイル: predictive-cursor.cpp プロジェクト: temita/groonga
bool PredictiveCursor::descending_next(Key *key) {
  while (!buf_.empty()) {
    const bool post_order = (buf_.back() & POST_ORDER_FLAG) == POST_ORDER_FLAG;
    const UInt32 node_id = buf_.back() & ~POST_ORDER_FLAG;

    const Base base = trie_->ith_node(node_id).base();
    if (post_order) {
      buf_.pop_back();
      if (base.is_terminal()) {
        Key temp_key;
        trie_->ith_key(base.key_id(), &temp_key);
        if (temp_key.length() >= min_length_) {
          if (cur_++ >= offset_) {
            *key = temp_key;
            return true;
          }
        }
      }
    } else {
      buf_.back() |= POST_ORDER_FLAG;
      UInt16 label = trie_->ith_node(node_id).child();
      while (label != INVALID_LABEL) {
        GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(base.offset() ^ label));
        label = trie_->ith_node(base.offset() ^ label).sibling();
      }
    }
  }
  return false;
}
コード例 #4
0
ファイル: key-cursor.cpp プロジェクト: mmmaru777/groonga
void KeyCursor::open(const Trie &trie,
                     const String &min_str,
                     const String &max_str,
                     UInt32 offset,
                     UInt32 limit,
                     UInt32 flags) {
  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(min_str, max_str);
  new_cursor.swap(this);
}
コード例 #5
0
ファイル: predictive-cursor.cpp プロジェクト: temita/groonga
UInt32 PredictiveCursor::fix_flags(UInt32 flags) const {
  const UInt32 cursor_type = flags & CURSOR_TYPE_MASK;
  GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_type != 0) &&
                                (cursor_type != PREDICTIVE_CURSOR));
  flags |= PREDICTIVE_CURSOR;

  const UInt32 cursor_order = flags & CURSOR_ORDER_MASK;
  GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_order != 0) &&
                                (cursor_order != ASCENDING_CURSOR) &&
                                (cursor_order != DESCENDING_CURSOR));
  if (cursor_order == 0) {
    flags |= ASCENDING_CURSOR;
  }

  const UInt32 cursor_options = flags & CURSOR_OPTIONS_MASK;
  GRN_DAT_THROW_IF(PARAM_ERROR, cursor_options & ~(EXCEPT_EXACT_MATCH));

  return flags;
}
コード例 #6
0
ファイル: id-cursor.cpp プロジェクト: bossato/groonga
UInt32 IdCursor::fix_flags(UInt32 flags) const {
  const UInt32 cursor_type = flags & CURSOR_TYPE_MASK;
  GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_type != 0) &&
                                (cursor_type != ID_RANGE_CURSOR));
  flags |= ID_RANGE_CURSOR;

  const UInt32 cursor_order = flags & CURSOR_ORDER_MASK;
  GRN_DAT_THROW_IF(PARAM_ERROR, (cursor_order != 0) &&
                                (cursor_order != ASCENDING_CURSOR) &&
                                (cursor_order != DESCENDING_CURSOR));
  if (cursor_order == 0) {
    flags |= ASCENDING_CURSOR;
  }

  const UInt32 cursor_options = flags & CURSOR_OPTIONS_MASK;
  GRN_DAT_THROW_IF(PARAM_ERROR,
      cursor_options & ~(EXCEPT_LOWER_BOUND | EXCEPT_UPPER_BOUND));

  return flags;
}
コード例 #7
0
ファイル: predictive-cursor.cpp プロジェクト: temita/groonga
void PredictiveCursor::open(const Trie &trie,
                            const String &str,
                            UInt32 offset,
                            UInt32 limit,
                            UInt32 flags) {
  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(str);
  new_cursor.swap(this);
}
コード例 #8
0
ファイル: predictive-cursor.cpp プロジェクト: temita/groonga
void PredictiveCursor::init(const String &str) {
  if (limit_ == 0) {
    return;
  }

  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 < 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() >= str.length()) &&
            (key.str().substr(0, str.length()).compare(str, i) == 0)) {
          if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
            node_id |= IS_ROOT_FLAG;
          }
          GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node_id));
        }
      }
      return;
    }

    node_id = base.offset() ^ str[i];
    if (trie_->ith_node(node_id).label() != str[i]) {
      return;
    }
  }

  if ((flags_ & ASCENDING_CURSOR) == ASCENDING_CURSOR) {
    node_id |= IS_ROOT_FLAG;
  }
  GRN_DAT_THROW_IF(MEMORY_ERROR, !buf_.push_back(node_id));
}
コード例 #9
0
ファイル: id-cursor.cpp プロジェクト: bossato/groonga
void IdCursor::open(const Trie &trie,
                    const String &min_str,
                    const String &max_str,
                    UInt32 offset,
                    UInt32 limit,
                    UInt32 flags) {
  UInt32 min_id = INVALID_KEY_ID;
  if (min_str.ptr() != NULL) {
    UInt32 key_pos;
    GRN_DAT_THROW_IF(PARAM_ERROR,
                     !trie.search(min_str.ptr(), min_str.length(), &key_pos));
    min_id = trie.get_key(key_pos).id();
  }

  UInt32 max_id = INVALID_KEY_ID;
  if (max_str.ptr() != NULL) {
    UInt32 key_pos;
    GRN_DAT_THROW_IF(PARAM_ERROR,
                     !trie.search(max_str.ptr(), max_str.length(), &key_pos));
    max_id = trie.get_key(key_pos).id();
  }

  open(trie, min_id, max_id, offset, limit, flags);
}
コード例 #10
0
ファイル: cursor-factory.cpp プロジェクト: AkioKanno/groonga
Cursor *CursorFactory::open(const Trie &trie,
                            const void *min_ptr, UInt32 min_length,
                            const void *max_ptr, UInt32 max_length,
                            UInt32 offset,
                            UInt32 limit,
                            UInt32 flags) {
  GRN_DAT_THROW_IF(PARAM_ERROR, &trie == NULL);

  const UInt32 cursor_type = flags & CURSOR_TYPE_MASK;
  switch (cursor_type) {
    case ID_RANGE_CURSOR: {
      IdCursor *cursor = new (std::nothrow) IdCursor;
      GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL);
      try {
        cursor->open(trie, String(min_ptr, min_length),
                     String(max_ptr, max_length), offset, limit, flags);
      } catch (...) {
        delete cursor;
        throw;
      }
      return cursor;
    }
    case KEY_RANGE_CURSOR: {
      KeyCursor *cursor = new (std::nothrow) KeyCursor;
      GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL);
      try {
        cursor->open(trie, String(min_ptr, min_length),
                     String(max_ptr, max_length), offset, limit, flags);
      } catch (...) {
        delete cursor;
        throw;
      }
      return cursor;
    }
    case PREFIX_CURSOR: {
      PrefixCursor *cursor = new (std::nothrow) PrefixCursor;
      GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL);
      try {
        cursor->open(trie, String(max_ptr, max_length), min_length,
                     offset, limit, flags);
      } catch (...) {
        delete cursor;
        throw;
      }
      return cursor;
    }
    case PREDICTIVE_CURSOR: {
      PredictiveCursor *cursor = new (std::nothrow) PredictiveCursor;
      GRN_DAT_THROW_IF(MEMORY_ERROR, cursor == NULL);
      try {
        cursor->open(trie, String(min_ptr, min_length),
                     offset, limit, flags);
      } catch (...) {
        delete cursor;
        throw;
      }
      return cursor;
    }
    default: {
      GRN_DAT_THROW(PARAM_ERROR, "unknown cursor type");
    }
  }
}