Download full Source Code here .
public class Designator
This class is designed and implemented to generate printable designator tag strings, with the theoretical target:
toString()
and
Designator(CharSequence)
constructor)
Comparable
interface or the
Designator.DesignatorComparator
class)
lower
and
upper
, if
lower.compareTo(upper) < 0
is true, then it is always possible to generate a new tag
middle
that between
lower
and
upper
, so
lower.compareTo(middle) < 0
and
upper.compareTo(middle) > 0
will both be true.
This class is so used to resolve sorting problems of sibling WoW nodes. Since WoW is web based thus allow concurrent modifications including inserting child nodes to a same parent node, maybe by many different users at the same time. And WoW use database instead of linear storage to store node data, so the sorting order of sibling nodes became quite unobvious. Using an integer number as the unique sequence number seems feasible but there will be situations when insert a new node between nodes designated by two integers that one directly follows another. Think about insert between 7 and 8, yes we can change the old 8 node's seq no to 9 and make the newly inserted 8. But there may already been 9, 10, 11 ... stand, in the worst case we'll have to modify all succeeding sibling nodes, as sequence numbers have to be persistent attributes, this will raise heavy concurrent contention risk.
Finally we need an sequencing schema that both allow random insertion at arbitrary positions and rarely need to change saved data. Then this class come into idea inspired by fractional arithmetic of the positional number system. You can find infinite numbers of fractional numbers between two of them. But that will produce more digits when these two number are very close, and the increase of digits is also infinite.
To determin whether a simular mechanism is suitable for WoW daily use, some estimation are made with this class, and the result shows the number of digits will exceed 250 only after randomly insert more than one million nodes under a particular one, since 250 is a reasonable tag length for modern data systems, it seems fairly feasible.
Technically, this class simulates a signed fractional number system with a base of 64. We use a single byte to store each digit value, this wastes 25% of the memory space but should be practically acceptable since it also improves the processing time performance. We use ASCII 0-9 A-Z a-z and { } as the digit symbols, and place them in their ASCII order, this simplifies and boosts comparation against string representations of designator tags.
Below are some estimation results produced by running the main(String[])
method.
Firing 30000 random insert session with each 100 records at max. Designator length exceeds 250 after fired 23486 insert sessions and inserted 1178115 records. ------------------------------------------------- Total inserted designators: 1504340 Longest one is [257]: +}}}}}}}}}}}}}}v03000000000000030000000F0E}}}}}{F00000}}}}}}y000000300000EU}}}}}}}x}}}Vw}{00002}}}}}}}}}}}x{00002}}}}}}}}}}}}}W00000000000000102l0000000002}}}}}}}}}}}x}}Vw{000000000000002}}}{00000V000030000000000}}{000000E}}}}}}}}}}t}}}}}}}}}}}000000000000V Average length: 117 Length above 2: 349 => 0‰ Length above 4: 1457 => 0‰ Length above 8: 7511 => 4‰ Length above 16: 41436 => 27‰ Length above 32: 145931 => 97‰ Length above 64: 657302 => 436‰ Length above 128: 650346 => 432‰ Length above 256: 8 => 0‰ Length above 512: 0 => 0‰ Errors: 0
Firing 30000 random insert session with each 100 records at max. Designator length exceeds 250 after fired 22650 insert sessions and inserted 1137011 records. ------------------------------------------------- Total inserted designators: 1503406 Longest one is [335]: -}}}}}}}}}}}}}}}}}}}}}}TlU}}}}}}}}}}}}}}}u00000000000100000000000000010000000U}}}}}}}y00000000000E}}}W0000U}}}}}}}}}l}}u00F000700F02}}}}V}}}}}}}}}V}}}}00000000000000002}}}}}}}}}}W00000000000000030000000000V02}}}}}}}}}}}}u000000000000000000}}}}}}}z}}}}}}}}y000000000000000002}}}{}}}}}}}}}}}}}{}}}}}}}}}00000000006}}}}}}}}}}}00000000000V Average length: 140 Length above 2: 349 => 0‰ Length above 4: 1381 => 0‰ Length above 8: 6133 => 4‰ Length above 16: 34476 => 22‰ Length above 32: 199236 => 132‰ Length above 64: 348206 => 231‰ Length above 128: 847748 => 563‰ Length above 256: 65877 => 43‰ Length above 512: 0 => 0‰ Errors: 0
Firing 30000 random insert session with each 100 records at max. Designator length exceeds 250 after fired 25835 insert sessions and inserted 1293752 records. ------------------------------------------------- Total inserted designators: 1504246 Longest one is [265]: +gl00V000000000000U}}}}{}}}}}}}}}}}}}{000000000000E}}}}z}}}}}{00000000000013002}}}}}u0000000000000000}}}}}}}}}}}}z}}}}}}}}{00000F0002zs}}{0000010000000000V000000000000003000000V000E}}}}}}z}}}}t}}}}}}z}m0000006}}}}}V}}{000001000000000000000030000000000E}}}}}}}}}}}}W Average length: 111 Length above 2: 335 => 0‰ Length above 4: 2101 => 1‰ Length above 8: 12525 => 8‰ Length above 16: 76643 => 50‰ Length above 32: 302603 => 201‰ Length above 64: 527695 => 350‰ Length above 128: 582167 => 387‰ Length above 256: 177 => 0‰ Length above 512: 0 => 0‰ Errors: 0