// The stack stores pairs of integers for backtracking to another // outbound edge of a branch node. // The first integer is an offset from uchars_. // The second integer has the str_.length() from before the node in bits 15..0, // and the remaining branch length in bits 31..16. // (We could store the remaining branch length minus 1 in bits 30..16 and not use the sign bit, // but the code looks more confusing that way.)
UVector32 *stack_;
};
// Helper functions for hasUniqueValue(). // Recursively finds a unique value (or whether there is not a unique one) // from a branch. staticconst char16_t *findUniqueValueFromBranch(const char16_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 unit. static UBool findUniqueValue(const char16_t *pos, UBool haveUniqueValue, int32_t &uniqueValue);
// Helper functions for getNextUChars(). // getNextUChars() when pos is on a branch node. staticvoid getNextBranchUChars(const char16_t *pos, int32_t length, Appendable &out);
// UCharsTrie data structure // // The trie consists of a series of char16_t-serialized nodes for incremental // Unicode string/char16_t sequence matching. (char16_t=16-bit unsigned integer) // The root node is at the beginning of the trie data. // // Types of nodes are distinguished by their node lead unit ranges. // After each node, except a final-value node, another node follows to // encode match values or continue matching further units. // // Node types: // - Final-value node: Stores a 32-bit integer in a compact, variable-length format. // The value is for the string/char16_t sequence so far. // - Match node, optionally with an intermediate value in a different compact format. // The value, if present, is for the string/char16_t sequence so far. // // Aside from the value, which uses the node lead unit's high bits: // // - Linear-match node: Matches a number of units. // - Branch node: Branches to other nodes according to the current input unit. // The node unit is the length of the branch (number of units 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 unit. // If one of the key units matches, then the value is either a final value for // the string so far, or a "jump" delta to the next node. // If the last unit matches, then matching continues with the next node. // (Values have the same encoding as final-value nodes.) // - If the length is greater than kMaxBranchLinearSubNodeLength, then // there is one unit and one "jump" delta. // If the input unit is less than the sub-node unit, 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.
// Match-node lead unit values, after masking off intermediate-value bits:
// 0000..002f: Branch node. If node!=0 then the length is node+1, otherwise // the length is one more than the next unit.
// For a branch sub-node with at most this many entries, we drop down // to a linear search. staticconst int32_t kMaxBranchLinearSubNodeLength=5;
// 0030..003f: Linear-match node, match 1..16 units and continue reading the next node. staticconst int32_t kMinLinearMatch=0x30; staticconst int32_t kMaxLinearMatchLength=0x10;
// Match-node lead unit bits 14..6 for the optional intermediate value. // If these bits are 0, then there is no intermediate value. // Otherwise, see the *NodeValue* constants below. staticconst int32_t kMinValueLead=kMinLinearMatch+kMaxLinearMatchLength; // 0x0040 staticconst int32_t kNodeTypeMask=kMinValueLead-1; // 0x003f
// A final-value node has bit 15 set. staticconst int32_t kValueIsFinal=0x8000;
// Compact value: After testing and masking off bit 15, use the following thresholds. staticconst int32_t kMaxOneUnitValue=0x3fff;
// Compact intermediate-value integer, lead unit shared with a branch or linear-match node. staticconst int32_t kMaxOneUnitNodeValue=0xff; staticconst int32_t kMinTwoUnitNodeValueLead=kMinValueLead+((kMaxOneUnitNodeValue+1)<<6); // 0x4040 staticconst int32_t kThreeUnitNodeValueLead=0x7fc0;
// 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;
char16_t *ownedArray_;
// Fixed value referencing the UCharsTrie words. const char16_t *uchars_;
// Iterator variables.
// Pointer to next trie unit to read. nullptr if no more matches. const char16_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.