1*ab8db090SAndroid Build Coastguard Worker #ifndef MARISA_GRIMOIRE_TRIE_KEY_H_ 2*ab8db090SAndroid Build Coastguard Worker #define MARISA_GRIMOIRE_TRIE_KEY_H_ 3*ab8db090SAndroid Build Coastguard Worker 4*ab8db090SAndroid Build Coastguard Worker #include "marisa/base.h" 5*ab8db090SAndroid Build Coastguard Worker 6*ab8db090SAndroid Build Coastguard Worker namespace marisa { 7*ab8db090SAndroid Build Coastguard Worker namespace grimoire { 8*ab8db090SAndroid Build Coastguard Worker namespace trie { 9*ab8db090SAndroid Build Coastguard Worker 10*ab8db090SAndroid Build Coastguard Worker class Key { 11*ab8db090SAndroid Build Coastguard Worker public: Key()12*ab8db090SAndroid Build Coastguard Worker Key() : ptr_(NULL), length_(0), union_(), id_(0) { 13*ab8db090SAndroid Build Coastguard Worker union_.terminal = 0; 14*ab8db090SAndroid Build Coastguard Worker } Key(const Key & entry)15*ab8db090SAndroid Build Coastguard Worker Key(const Key &entry) 16*ab8db090SAndroid Build Coastguard Worker : ptr_(entry.ptr_), length_(entry.length_), 17*ab8db090SAndroid Build Coastguard Worker union_(entry.union_), id_(entry.id_) {} 18*ab8db090SAndroid Build Coastguard Worker 19*ab8db090SAndroid Build Coastguard Worker Key &operator=(const Key &entry) { 20*ab8db090SAndroid Build Coastguard Worker ptr_ = entry.ptr_; 21*ab8db090SAndroid Build Coastguard Worker length_ = entry.length_; 22*ab8db090SAndroid Build Coastguard Worker union_ = entry.union_; 23*ab8db090SAndroid Build Coastguard Worker id_ = entry.id_; 24*ab8db090SAndroid Build Coastguard Worker return *this; 25*ab8db090SAndroid Build Coastguard Worker } 26*ab8db090SAndroid Build Coastguard Worker 27*ab8db090SAndroid Build Coastguard Worker char operator[](std::size_t i) const { 28*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(i >= length_, MARISA_BOUND_ERROR); 29*ab8db090SAndroid Build Coastguard Worker return ptr_[i]; 30*ab8db090SAndroid Build Coastguard Worker } 31*ab8db090SAndroid Build Coastguard Worker substr(std::size_t pos,std::size_t length)32*ab8db090SAndroid Build Coastguard Worker void substr(std::size_t pos, std::size_t length) { 33*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(pos > length_, MARISA_BOUND_ERROR); 34*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(length > length_, MARISA_BOUND_ERROR); 35*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(pos > (length_ - length), MARISA_BOUND_ERROR); 36*ab8db090SAndroid Build Coastguard Worker ptr_ += pos; 37*ab8db090SAndroid Build Coastguard Worker length_ = (UInt32)length; 38*ab8db090SAndroid Build Coastguard Worker } 39*ab8db090SAndroid Build Coastguard Worker set_str(const char * ptr,std::size_t length)40*ab8db090SAndroid Build Coastguard Worker void set_str(const char *ptr, std::size_t length) { 41*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF((ptr == NULL) && (length != 0), MARISA_NULL_ERROR); 42*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(length > MARISA_UINT32_MAX, MARISA_SIZE_ERROR); 43*ab8db090SAndroid Build Coastguard Worker ptr_ = ptr; 44*ab8db090SAndroid Build Coastguard Worker length_ = (UInt32)length; 45*ab8db090SAndroid Build Coastguard Worker } set_weight(float weight)46*ab8db090SAndroid Build Coastguard Worker void set_weight(float weight) { 47*ab8db090SAndroid Build Coastguard Worker union_.weight = weight; 48*ab8db090SAndroid Build Coastguard Worker } set_terminal(std::size_t terminal)49*ab8db090SAndroid Build Coastguard Worker void set_terminal(std::size_t terminal) { 50*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(terminal > MARISA_UINT32_MAX, MARISA_SIZE_ERROR); 51*ab8db090SAndroid Build Coastguard Worker union_.terminal = (UInt32)terminal; 52*ab8db090SAndroid Build Coastguard Worker } set_id(std::size_t id)53*ab8db090SAndroid Build Coastguard Worker void set_id(std::size_t id) { 54*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR); 55*ab8db090SAndroid Build Coastguard Worker id_ = (UInt32)id; 56*ab8db090SAndroid Build Coastguard Worker } 57*ab8db090SAndroid Build Coastguard Worker ptr()58*ab8db090SAndroid Build Coastguard Worker const char *ptr() const { 59*ab8db090SAndroid Build Coastguard Worker return ptr_; 60*ab8db090SAndroid Build Coastguard Worker } length()61*ab8db090SAndroid Build Coastguard Worker std::size_t length() const { 62*ab8db090SAndroid Build Coastguard Worker return length_; 63*ab8db090SAndroid Build Coastguard Worker } weight()64*ab8db090SAndroid Build Coastguard Worker float weight() const { 65*ab8db090SAndroid Build Coastguard Worker return union_.weight; 66*ab8db090SAndroid Build Coastguard Worker } terminal()67*ab8db090SAndroid Build Coastguard Worker std::size_t terminal() const { 68*ab8db090SAndroid Build Coastguard Worker return union_.terminal; 69*ab8db090SAndroid Build Coastguard Worker } id()70*ab8db090SAndroid Build Coastguard Worker std::size_t id() const { 71*ab8db090SAndroid Build Coastguard Worker return id_; 72*ab8db090SAndroid Build Coastguard Worker } 73*ab8db090SAndroid Build Coastguard Worker 74*ab8db090SAndroid Build Coastguard Worker private: 75*ab8db090SAndroid Build Coastguard Worker const char *ptr_; 76*ab8db090SAndroid Build Coastguard Worker UInt32 length_; 77*ab8db090SAndroid Build Coastguard Worker union Union { 78*ab8db090SAndroid Build Coastguard Worker float weight; 79*ab8db090SAndroid Build Coastguard Worker UInt32 terminal; 80*ab8db090SAndroid Build Coastguard Worker } union_; 81*ab8db090SAndroid Build Coastguard Worker UInt32 id_; 82*ab8db090SAndroid Build Coastguard Worker }; 83*ab8db090SAndroid Build Coastguard Worker 84*ab8db090SAndroid Build Coastguard Worker inline bool operator==(const Key &lhs, const Key &rhs) { 85*ab8db090SAndroid Build Coastguard Worker if (lhs.length() != rhs.length()) { 86*ab8db090SAndroid Build Coastguard Worker return false; 87*ab8db090SAndroid Build Coastguard Worker } 88*ab8db090SAndroid Build Coastguard Worker for (std::size_t i = 0; i < lhs.length(); ++i) { 89*ab8db090SAndroid Build Coastguard Worker if (lhs[i] != rhs[i]) { 90*ab8db090SAndroid Build Coastguard Worker return false; 91*ab8db090SAndroid Build Coastguard Worker } 92*ab8db090SAndroid Build Coastguard Worker } 93*ab8db090SAndroid Build Coastguard Worker return true; 94*ab8db090SAndroid Build Coastguard Worker } 95*ab8db090SAndroid Build Coastguard Worker 96*ab8db090SAndroid Build Coastguard Worker inline bool operator!=(const Key &lhs, const Key &rhs) { 97*ab8db090SAndroid Build Coastguard Worker return !(lhs == rhs); 98*ab8db090SAndroid Build Coastguard Worker } 99*ab8db090SAndroid Build Coastguard Worker 100*ab8db090SAndroid Build Coastguard Worker inline bool operator<(const Key &lhs, const Key &rhs) { 101*ab8db090SAndroid Build Coastguard Worker for (std::size_t i = 0; i < lhs.length(); ++i) { 102*ab8db090SAndroid Build Coastguard Worker if (i == rhs.length()) { 103*ab8db090SAndroid Build Coastguard Worker return false; 104*ab8db090SAndroid Build Coastguard Worker } 105*ab8db090SAndroid Build Coastguard Worker if (lhs[i] != rhs[i]) { 106*ab8db090SAndroid Build Coastguard Worker return (UInt8)lhs[i] < (UInt8)rhs[i]; 107*ab8db090SAndroid Build Coastguard Worker } 108*ab8db090SAndroid Build Coastguard Worker } 109*ab8db090SAndroid Build Coastguard Worker return lhs.length() < rhs.length(); 110*ab8db090SAndroid Build Coastguard Worker } 111*ab8db090SAndroid Build Coastguard Worker 112*ab8db090SAndroid Build Coastguard Worker inline bool operator>(const Key &lhs, const Key &rhs) { 113*ab8db090SAndroid Build Coastguard Worker return rhs < lhs; 114*ab8db090SAndroid Build Coastguard Worker } 115*ab8db090SAndroid Build Coastguard Worker 116*ab8db090SAndroid Build Coastguard Worker class ReverseKey { 117*ab8db090SAndroid Build Coastguard Worker public: ReverseKey()118*ab8db090SAndroid Build Coastguard Worker ReverseKey() : ptr_(NULL), length_(0), union_(), id_(0) { 119*ab8db090SAndroid Build Coastguard Worker union_.terminal = 0; 120*ab8db090SAndroid Build Coastguard Worker } ReverseKey(const ReverseKey & entry)121*ab8db090SAndroid Build Coastguard Worker ReverseKey(const ReverseKey &entry) 122*ab8db090SAndroid Build Coastguard Worker : ptr_(entry.ptr_), length_(entry.length_), 123*ab8db090SAndroid Build Coastguard Worker union_(entry.union_), id_(entry.id_) {} 124*ab8db090SAndroid Build Coastguard Worker 125*ab8db090SAndroid Build Coastguard Worker ReverseKey &operator=(const ReverseKey &entry) { 126*ab8db090SAndroid Build Coastguard Worker ptr_ = entry.ptr_; 127*ab8db090SAndroid Build Coastguard Worker length_ = entry.length_; 128*ab8db090SAndroid Build Coastguard Worker union_ = entry.union_; 129*ab8db090SAndroid Build Coastguard Worker id_ = entry.id_; 130*ab8db090SAndroid Build Coastguard Worker return *this; 131*ab8db090SAndroid Build Coastguard Worker } 132*ab8db090SAndroid Build Coastguard Worker 133*ab8db090SAndroid Build Coastguard Worker char operator[](std::size_t i) const { 134*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(i >= length_, MARISA_BOUND_ERROR); 135*ab8db090SAndroid Build Coastguard Worker return *(ptr_ - i - 1); 136*ab8db090SAndroid Build Coastguard Worker } 137*ab8db090SAndroid Build Coastguard Worker substr(std::size_t pos,std::size_t length)138*ab8db090SAndroid Build Coastguard Worker void substr(std::size_t pos, std::size_t length) { 139*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(pos > length_, MARISA_BOUND_ERROR); 140*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(length > length_, MARISA_BOUND_ERROR); 141*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(pos > (length_ - length), MARISA_BOUND_ERROR); 142*ab8db090SAndroid Build Coastguard Worker ptr_ -= pos; 143*ab8db090SAndroid Build Coastguard Worker length_ = (UInt32)length; 144*ab8db090SAndroid Build Coastguard Worker } 145*ab8db090SAndroid Build Coastguard Worker set_str(const char * ptr,std::size_t length)146*ab8db090SAndroid Build Coastguard Worker void set_str(const char *ptr, std::size_t length) { 147*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF((ptr == NULL) && (length != 0), MARISA_NULL_ERROR); 148*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(length > MARISA_UINT32_MAX, MARISA_SIZE_ERROR); 149*ab8db090SAndroid Build Coastguard Worker ptr_ = ptr + length; 150*ab8db090SAndroid Build Coastguard Worker length_ = (UInt32)length; 151*ab8db090SAndroid Build Coastguard Worker } set_weight(float weight)152*ab8db090SAndroid Build Coastguard Worker void set_weight(float weight) { 153*ab8db090SAndroid Build Coastguard Worker union_.weight = weight; 154*ab8db090SAndroid Build Coastguard Worker } set_terminal(std::size_t terminal)155*ab8db090SAndroid Build Coastguard Worker void set_terminal(std::size_t terminal) { 156*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(terminal > MARISA_UINT32_MAX, MARISA_SIZE_ERROR); 157*ab8db090SAndroid Build Coastguard Worker union_.terminal = (UInt32)terminal; 158*ab8db090SAndroid Build Coastguard Worker } set_id(std::size_t id)159*ab8db090SAndroid Build Coastguard Worker void set_id(std::size_t id) { 160*ab8db090SAndroid Build Coastguard Worker MARISA_DEBUG_IF(id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR); 161*ab8db090SAndroid Build Coastguard Worker id_ = (UInt32)id; 162*ab8db090SAndroid Build Coastguard Worker } 163*ab8db090SAndroid Build Coastguard Worker ptr()164*ab8db090SAndroid Build Coastguard Worker const char *ptr() const { 165*ab8db090SAndroid Build Coastguard Worker return ptr_ - length_; 166*ab8db090SAndroid Build Coastguard Worker } length()167*ab8db090SAndroid Build Coastguard Worker std::size_t length() const { 168*ab8db090SAndroid Build Coastguard Worker return length_; 169*ab8db090SAndroid Build Coastguard Worker } weight()170*ab8db090SAndroid Build Coastguard Worker float weight() const { 171*ab8db090SAndroid Build Coastguard Worker return union_.weight; 172*ab8db090SAndroid Build Coastguard Worker } terminal()173*ab8db090SAndroid Build Coastguard Worker std::size_t terminal() const { 174*ab8db090SAndroid Build Coastguard Worker return union_.terminal; 175*ab8db090SAndroid Build Coastguard Worker } id()176*ab8db090SAndroid Build Coastguard Worker std::size_t id() const { 177*ab8db090SAndroid Build Coastguard Worker return id_; 178*ab8db090SAndroid Build Coastguard Worker } 179*ab8db090SAndroid Build Coastguard Worker 180*ab8db090SAndroid Build Coastguard Worker private: 181*ab8db090SAndroid Build Coastguard Worker const char *ptr_; 182*ab8db090SAndroid Build Coastguard Worker UInt32 length_; 183*ab8db090SAndroid Build Coastguard Worker union Union { 184*ab8db090SAndroid Build Coastguard Worker float weight; 185*ab8db090SAndroid Build Coastguard Worker UInt32 terminal; 186*ab8db090SAndroid Build Coastguard Worker } union_; 187*ab8db090SAndroid Build Coastguard Worker UInt32 id_; 188*ab8db090SAndroid Build Coastguard Worker }; 189*ab8db090SAndroid Build Coastguard Worker 190*ab8db090SAndroid Build Coastguard Worker inline bool operator==(const ReverseKey &lhs, const ReverseKey &rhs) { 191*ab8db090SAndroid Build Coastguard Worker if (lhs.length() != rhs.length()) { 192*ab8db090SAndroid Build Coastguard Worker return false; 193*ab8db090SAndroid Build Coastguard Worker } 194*ab8db090SAndroid Build Coastguard Worker for (std::size_t i = 0; i < lhs.length(); ++i) { 195*ab8db090SAndroid Build Coastguard Worker if (lhs[i] != rhs[i]) { 196*ab8db090SAndroid Build Coastguard Worker return false; 197*ab8db090SAndroid Build Coastguard Worker } 198*ab8db090SAndroid Build Coastguard Worker } 199*ab8db090SAndroid Build Coastguard Worker return true; 200*ab8db090SAndroid Build Coastguard Worker } 201*ab8db090SAndroid Build Coastguard Worker 202*ab8db090SAndroid Build Coastguard Worker inline bool operator!=(const ReverseKey &lhs, const ReverseKey &rhs) { 203*ab8db090SAndroid Build Coastguard Worker return !(lhs == rhs); 204*ab8db090SAndroid Build Coastguard Worker } 205*ab8db090SAndroid Build Coastguard Worker 206*ab8db090SAndroid Build Coastguard Worker inline bool operator<(const ReverseKey &lhs, const ReverseKey &rhs) { 207*ab8db090SAndroid Build Coastguard Worker for (std::size_t i = 0; i < lhs.length(); ++i) { 208*ab8db090SAndroid Build Coastguard Worker if (i == rhs.length()) { 209*ab8db090SAndroid Build Coastguard Worker return false; 210*ab8db090SAndroid Build Coastguard Worker } 211*ab8db090SAndroid Build Coastguard Worker if (lhs[i] != rhs[i]) { 212*ab8db090SAndroid Build Coastguard Worker return (UInt8)lhs[i] < (UInt8)rhs[i]; 213*ab8db090SAndroid Build Coastguard Worker } 214*ab8db090SAndroid Build Coastguard Worker } 215*ab8db090SAndroid Build Coastguard Worker return lhs.length() < rhs.length(); 216*ab8db090SAndroid Build Coastguard Worker } 217*ab8db090SAndroid Build Coastguard Worker 218*ab8db090SAndroid Build Coastguard Worker inline bool operator>(const ReverseKey &lhs, const ReverseKey &rhs) { 219*ab8db090SAndroid Build Coastguard Worker return rhs < lhs; 220*ab8db090SAndroid Build Coastguard Worker } 221*ab8db090SAndroid Build Coastguard Worker 222*ab8db090SAndroid Build Coastguard Worker } // namespace trie 223*ab8db090SAndroid Build Coastguard Worker } // namespace grimoire 224*ab8db090SAndroid Build Coastguard Worker } // namespace marisa 225*ab8db090SAndroid Build Coastguard Worker 226*ab8db090SAndroid Build Coastguard Worker #endif // MARISA_GRIMOIRE_TRIE_KEY_H_ 227