// The stack stores pairs of integers for backtracking to another // outbound edge of a branch node. // The first integer is an offset from bytes_. // The second integer has the str_->length() from before the node in bits 15..0, // and the remaining branch length in bits 24..16. (Bits 31..25 are unused.) // (We could store the remaining branch length minus 1 in bits 23..16 and not use bits 31..24, // but the code looks more confusing that way.)
UVector32 *stack_;
};
private:
friend class BytesTrieBuilder;
friend class ::BytesTrieTest;
// Helper functions for hasUniqueValue(). // Recursively finds a unique value (or whether there is not a unique one) // from a branch. staticconst uint8_t *findUniqueValueFromBranch(const uint8_t *pos, int32_t length,
UBool haveUniqueValue, int32_t &uniqueValue); // Recursively finds a unique value (or whether there is not a unique one) // starting from a position on a node lead byte. static UBool findUniqueValue(const uint8_t *pos, UBool haveUniqueValue, int32_t &uniqueValue);
// Helper functions for getNextBytes(). // getNextBytes() when pos is on a branch node. staticvoid getNextBranchBytes(const uint8_t *pos, int32_t length, ByteSink &out); staticvoid append(ByteSink &out, int c);
// BytesTrie data structure // // The trie consists of a series of byte-serialized nodes for incremental // string/byte sequence matching. The root node is at the beginning of the trie data. // // Types of nodes are distinguished by their node lead byte ranges. // After each node, except a final-value node, another node follows to // encode match values or continue matching further bytes. // // Node types: // - Value node: Stores a 32-bit integer in a compact, variable-length format. // The value is for the string/byte sequence so far. // One node bit indicates whether the value is final or whether // matching continues with the next node. // - Linear-match node: Matches a number of bytes. // - Branch node: Branches to other nodes according to the current input byte. // The node byte is the length of the branch (number of bytes to select from) // minus 1. It is followed by a sub-node: // - If the length is at most kMaxBranchLinearSubNodeLength, then // there are length-1 (key, value) pairs and then one more comparison byte. // If one of the key bytes matches, then the value is either a final value for // the string/byte sequence so far, or a "jump" delta to the next node. // If the last byte matches, then matching continues with the next node. // (Values have the same encoding as value nodes.) // - If the length is greater than kMaxBranchLinearSubNodeLength, then // there is one byte and one "jump" delta. // If the input byte is less than the sub-node byte, then "jump" by delta to // the next sub-node which will have a length of length/2. // (The delta has its own compact encoding.) // Otherwise, skip the "jump" delta to the next sub-node // which will have a length of length-length/2.
// Node lead byte values.
// 00..0f: Branch node. If node!=0 then the length is node+1, otherwise // the length is one more than the next byte.
// For a branch sub-node with at most this many entries, we drop down // to a linear search. staticconst int32_t kMaxBranchLinearSubNodeLength=5;
// 10..1f: Linear-match node, match 1..16 bytes and continue reading the next node. staticconst int32_t kMinLinearMatch=0x10; staticconst int32_t kMaxLinearMatchLength=0x10;
// 20..ff: Variable-length value node. // If odd, the value is final. (Otherwise, intermediate value or jump delta.) // Then shift-right by 1 bit. // The remaining lead byte value indicates the number of following bytes (0..4) // and contains the value's top bits. staticconst int32_t kMinValueLead=kMinLinearMatch+kMaxLinearMatchLength; // 0x20 // It is a final value if bit 0 is set. staticconst int32_t kValueIsFinal=1;
// Compact value: After testing bit 0, shift right by 1 and then use the following thresholds. staticconst int32_t kMinOneByteValueLead=kMinValueLead/2; // 0x10 staticconst int32_t kMaxOneByteValue=0x40; // At least 6 bits in the first byte.
// For getState64(): // The remainingMatchLength_ is -1..14=(kMaxLinearMatchLength=0x10)-2 // so we need at least 5 bits for that. // We add 2 to store it as a positive value 1..16=kMaxLinearMatchLength. static constexpr int32_t kState64RemainingShift = 59; static constexpr uint64_t kState64PosMask = (UINT64_C(1) << kState64RemainingShift) - 1;
uint8_t *ownedArray_;
// Fixed value referencing the BytesTrie bytes. const uint8_t *bytes_;
// Iterator variables.
// Pointer to next trie byte to read. nullptr if no more matches. const uint8_t *pos_; // Remaining length of a linear-match node, minus 1. Negative if not in such a node.
int32_t remainingMatchLength_;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.