blob: e1f62c3e14df1ddc63b4d5db139f979ec1f53fb1 [file] [log] [blame]
// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef MOZC_STORAGE_LOUDS_LOUDS_TRIE_H_
#define MOZC_STORAGE_LOUDS_LOUDS_TRIE_H_
#include "base/port.h"
#include "base/string_piece.h"
#include "storage/louds/key_expansion_table.h"
#include "storage/louds/louds.h"
#include "storage/louds/simple_succinct_bit_vector_index.h"
namespace mozc {
namespace storage {
namespace louds {
// Implementation of a trie, based on the LOUDS (Level-Ordered Unary Degree
// Sequence) data structure.
// The "string" this class can handle as a key is c-style string
// (i.e. '\0'-terminated char array).
// TODO(hidehiko): Parametrize succinct bit vector implementation.
class LoudsTrie {
public:
// The max depth of the trie.
static const size_t kMaxDepth = 256;
// Interface which is called back when the result is found.
class Callback {
public:
enum ResultType {
// Finishes the current (prefix or predictive) search.
SEARCH_DONE,
// Continues the current (prefix or predictive) search.
SEARCH_CONTINUE,
// Finished the (prefix or predictive) search of the current edge,
// but still continues to search for other edges.
SEARCH_CULL,
};
virtual ~Callback() {
}
// The callback will be invoked when a target word is found.
// "s" may not be null-terminated.
virtual ResultType Run(const char *s, size_t len, int key_id) = 0;
protected:
Callback() {}
};
LoudsTrie() : edge_character_(NULL) {
}
~LoudsTrie() {
}
// Opens the binary image, and constructs the data structure.
// This method doesn't own the "data", so it is caller's reponsibility
// to keep the data alive until Close is invoked.
// See .cc file for the detailed format of the binary image.
bool Open(const uint8 *data);
// Destructs the internal data structure.
void Close();
// Searches the trie for the key that exactly matches the given key. Returns
// -1 if the key doesn't exist.
// TODO(noriyukit): Implement a callback style method if necessary.
int ExactSearch(const StringPiece key) const;
// Searches the trie structure, and invokes callback->Run when for each word
// which is a prefix of the key is found.
void PrefixSearch(const char *key, Callback *callback) const {
PrefixSearchWithKeyExpansion(
key, KeyExpansionTable::GetDefaultInstance(), callback);
}
void PrefixSearchWithKeyExpansion(
const char *key, const KeyExpansionTable &key_expansion_table,
Callback *callback) const;
// Searches the trie structure, and invokes callback->Run when for each word
// which begins with key is found.
void PredictiveSearch(const char *key, Callback *callback) const {
PredictiveSearchWithKeyExpansion(
key, KeyExpansionTable::GetDefaultInstance(), callback);
}
void PredictiveSearchWithKeyExpansion(
const char *key, const KeyExpansionTable &key_expansion_table,
Callback *callback) const;
// Traverses the trie from leaf to root and store the characters annotated to
// the edges. The size of the buffer should be larger than kMaxDepth. Returns
// the pointer to the first character.
const char *Reverse(int key_id, char *buf) const;
private:
// Tree-structure represented in LOUDS.
Louds trie_;
// Bit-vector to represent whether each node in LOUDS tree is terminal.
// This bit vector doesn't include "super root" in the LOUDS.
// In other words, id=1 in trie_ corresponds to id=0 in terminal_bit_vector_,
// id=10 in trie_ corresponds to id=9 in terminal_bit_vector_, and so on.
// TODO(hidehiko): Simplify the id-mapping by introducing a bit for the
// super root in this bit vector.
SimpleSuccinctBitVectorIndex terminal_bit_vector_;
// A sequence of characters, annotated to each edge.
// This array also doesn't have an entry for super root.
// In other words, id=2 in trie_ corresponds to edge_character_[1].
const char *edge_character_;
DISALLOW_COPY_AND_ASSIGN(LoudsTrie);
};
} // namespace louds
} // namespace storage
} // namespace mozc
#endif // MOZC_STORAGE_LOUDS_LOUDS_TRIE_H_