00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __STRINGTRIEBUILDER_H__
00018 #define __STRINGTRIEBUILDER_H__
00019
00020 #include "unicode/utypes.h"
00021
00022 #if U_SHOW_CPLUSPLUS_API
00023
00024 #include "unicode/uobject.h"
00025
00031
00033 struct UHashtable;
00034 typedef struct UHashtable UHashtable;
00036
00041 enum UStringTrieBuildOption {
00046 USTRINGTRIE_BUILD_FAST,
00057 USTRINGTRIE_BUILD_SMALL
00058 };
00059
00060 U_NAMESPACE_BEGIN
00061
00068 class U_COMMON_API StringTrieBuilder : public UObject {
00069 public:
00070 #ifndef U_HIDE_INTERNAL_API
00071
00072 static int32_t hashNode(const void *node);
00074 static UBool equalNodes(const void *left, const void *right);
00075 #endif
00076
00077 protected:
00078
00079
00081 StringTrieBuilder();
00083 virtual ~StringTrieBuilder();
00084
00085 #ifndef U_HIDE_INTERNAL_API
00086
00087 void createCompactBuilder(int32_t sizeGuess, UErrorCode &errorCode);
00089 void deleteCompactBuilder();
00090
00092 void build(UStringTrieBuildOption buildOption, int32_t elementsLength, UErrorCode &errorCode);
00093
00095 int32_t writeNode(int32_t start, int32_t limit, int32_t unitIndex);
00097 int32_t writeBranchSubNode(int32_t start, int32_t limit, int32_t unitIndex, int32_t length);
00098 #endif
00099
00100 class Node;
00101
00102 #ifndef U_HIDE_INTERNAL_API
00103
00104 Node *makeNode(int32_t start, int32_t limit, int32_t unitIndex, UErrorCode &errorCode);
00106 Node *makeBranchSubNode(int32_t start, int32_t limit, int32_t unitIndex,
00107 int32_t length, UErrorCode &errorCode);
00108 #endif
00109
00111 virtual int32_t getElementStringLength(int32_t i) const = 0;
00113 virtual char16_t getElementUnit(int32_t i, int32_t unitIndex) const = 0;
00115 virtual int32_t getElementValue(int32_t i) const = 0;
00116
00117
00118
00120 virtual int32_t getLimitOfLinearMatch(int32_t first, int32_t last, int32_t unitIndex) const = 0;
00121
00122
00124 virtual int32_t countElementUnits(int32_t start, int32_t limit, int32_t unitIndex) const = 0;
00126 virtual int32_t skipElementsBySomeUnits(int32_t i, int32_t unitIndex, int32_t count) const = 0;
00128 virtual int32_t indexOfElementWithNextUnit(int32_t i, int32_t unitIndex, char16_t unit) const = 0;
00129
00131 virtual UBool matchNodesCanHaveValues() const = 0;
00132
00134 virtual int32_t getMaxBranchLinearSubNodeLength() const = 0;
00136 virtual int32_t getMinLinearMatch() const = 0;
00138 virtual int32_t getMaxLinearMatchLength() const = 0;
00139
00140 #ifndef U_HIDE_INTERNAL_API
00141
00143 static const int32_t kMaxBranchLinearSubNodeLength=5;
00144
00145
00146
00148 static const int32_t kMaxSplitBranchLevels=14;
00149
00160 Node *registerNode(Node *newNode, UErrorCode &errorCode);
00171 Node *registerFinalValue(int32_t value, UErrorCode &errorCode);
00172 #endif
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00192 UHashtable *nodes;
00193
00194
00195
00200 class Node : public UObject {
00201 public:
00202 Node(int32_t initialHash) : hash(initialHash), offset(0) {}
00203 inline int32_t hashCode() const { return hash; }
00204
00205 static inline int32_t hashCode(const Node *node) { return node==NULL ? 0 : node->hashCode(); }
00206
00207 virtual UBool operator==(const Node &other) const;
00208 inline UBool operator!=(const Node &other) const { return !operator==(other); }
00236 virtual int32_t markRightEdgesFirst(int32_t edgeNumber);
00237
00238 virtual void write(StringTrieBuilder &builder) = 0;
00239
00240 inline void writeUnlessInsideRightEdge(int32_t firstRight, int32_t lastRight,
00241 StringTrieBuilder &builder) {
00242
00243
00244
00245
00246
00247 if(offset<0 && (offset<lastRight || firstRight<offset)) {
00248 write(builder);
00249 }
00250 }
00251 inline int32_t getOffset() const { return offset; }
00252 protected:
00253 int32_t hash;
00254 int32_t offset;
00255 };
00256
00257 #ifndef U_HIDE_INTERNAL_API
00258
00259
00260
00261
00262
00263
00265 class FinalValueNode : public Node {
00266 public:
00267 FinalValueNode(int32_t v) : Node(0x111111u*37u+v), value(v) {}
00268 virtual UBool operator==(const Node &other) const;
00269 virtual void write(StringTrieBuilder &builder);
00270 protected:
00271 int32_t value;
00272 };
00273 #endif
00274
00275
00276
00280 class ValueNode : public Node {
00281 public:
00282 ValueNode(int32_t initialHash) : Node(initialHash), hasValue(FALSE), value(0) {}
00283 virtual UBool operator==(const Node &other) const;
00284 void setValue(int32_t v) {
00285 hasValue=TRUE;
00286 value=v;
00287 hash=hash*37u+v;
00288 }
00289 protected:
00290 UBool hasValue;
00291 int32_t value;
00292 };
00293
00294 #ifndef U_HIDE_INTERNAL_API
00295
00298 class IntermediateValueNode : public ValueNode {
00299 public:
00300 IntermediateValueNode(int32_t v, Node *nextNode)
00301 : ValueNode(0x222222u*37u+hashCode(nextNode)), next(nextNode) { setValue(v); }
00302 virtual UBool operator==(const Node &other) const;
00303 virtual int32_t markRightEdgesFirst(int32_t edgeNumber);
00304 virtual void write(StringTrieBuilder &builder);
00305 protected:
00306 Node *next;
00307 };
00308 #endif
00309
00310
00311
00315 class LinearMatchNode : public ValueNode {
00316 public:
00317 LinearMatchNode(int32_t len, Node *nextNode)
00318 : ValueNode((0x333333u*37u+len)*37u+hashCode(nextNode)),
00319 length(len), next(nextNode) {}
00320 virtual UBool operator==(const Node &other) const;
00321 virtual int32_t markRightEdgesFirst(int32_t edgeNumber);
00322 protected:
00323 int32_t length;
00324 Node *next;
00325 };
00326
00327 #ifndef U_HIDE_INTERNAL_API
00328
00331 class BranchNode : public Node {
00332 public:
00333 BranchNode(int32_t initialHash) : Node(initialHash) {}
00334 protected:
00335 int32_t firstEdgeNumber;
00336 };
00337
00341 class ListBranchNode : public BranchNode {
00342 public:
00343 ListBranchNode() : BranchNode(0x444444), length(0) {}
00344 virtual UBool operator==(const Node &other) const;
00345 virtual int32_t markRightEdgesFirst(int32_t edgeNumber);
00346 virtual void write(StringTrieBuilder &builder);
00347
00348 void add(int32_t c, int32_t value) {
00349 units[length]=(char16_t)c;
00350 equal[length]=NULL;
00351 values[length]=value;
00352 ++length;
00353 hash=(hash*37u+c)*37u+value;
00354 }
00355
00356 void add(int32_t c, Node *node) {
00357 units[length]=(char16_t)c;
00358 equal[length]=node;
00359 values[length]=0;
00360 ++length;
00361 hash=(hash*37u+c)*37u+hashCode(node);
00362 }
00363 protected:
00364 Node *equal[kMaxBranchLinearSubNodeLength];
00365 int32_t length;
00366 int32_t values[kMaxBranchLinearSubNodeLength];
00367 char16_t units[kMaxBranchLinearSubNodeLength];
00368 };
00369
00373 class SplitBranchNode : public BranchNode {
00374 public:
00375 SplitBranchNode(char16_t middleUnit, Node *lessThanNode, Node *greaterOrEqualNode)
00376 : BranchNode(((0x555555u*37u+middleUnit)*37u+
00377 hashCode(lessThanNode))*37u+hashCode(greaterOrEqualNode)),
00378 unit(middleUnit), lessThan(lessThanNode), greaterOrEqual(greaterOrEqualNode) {}
00379 virtual UBool operator==(const Node &other) const;
00380 virtual int32_t markRightEdgesFirst(int32_t edgeNumber);
00381 virtual void write(StringTrieBuilder &builder);
00382 protected:
00383 char16_t unit;
00384 Node *lessThan;
00385 Node *greaterOrEqual;
00386 };
00387
00388
00390 class BranchHeadNode : public ValueNode {
00391 public:
00392 BranchHeadNode(int32_t len, Node *subNode)
00393 : ValueNode((0x666666u*37u+len)*37u+hashCode(subNode)),
00394 length(len), next(subNode) {}
00395 virtual UBool operator==(const Node &other) const;
00396 virtual int32_t markRightEdgesFirst(int32_t edgeNumber);
00397 virtual void write(StringTrieBuilder &builder);
00398 protected:
00399 int32_t length;
00400 Node *next;
00401 };
00402
00403 #endif
00405
00406
00407 virtual Node *createLinearMatchNode(int32_t i, int32_t unitIndex, int32_t length,
00408 Node *nextNode) const = 0;
00409
00411 virtual int32_t write(int32_t unit) = 0;
00413 virtual int32_t writeElementUnits(int32_t i, int32_t unitIndex, int32_t length) = 0;
00415 virtual int32_t writeValueAndFinal(int32_t i, UBool isFinal) = 0;
00417 virtual int32_t writeValueAndType(UBool hasValue, int32_t value, int32_t node) = 0;
00419 virtual int32_t writeDeltaTo(int32_t jumpTarget) = 0;
00420 };
00421
00422 U_NAMESPACE_END
00423
00424 #endif
00425
00426 #endif // __STRINGTRIEBUILDER_H__