public void Test54TruncatingIteratorFromLinearMatchLong() { StringAndValue[] data = { new StringAndValue("abcdef", 10), new StringAndValue("abcdepq", 200), new StringAndValue("abcdeyz", 3000) }; BytesTrie trie = buildTrie(data, data.Length, TrieBuilderOption.Fast); // Go into a linear-match node. trie.Next('a'); trie.Next('b'); trie.Next('c'); // Truncate after the linear-match node. BytesTrieEnumerator iter = trie.GetEnumerator(3); StringAndValue[] expected = { new StringAndValue("def", 10), new StringAndValue("dep", -1), new StringAndValue("dey", -1) }; checkIterator(iter, expected); // Reset, and we should get the same result. Logln("after iter.Reset()"); checkIterator(iter.Reset(), expected); }
private void checkFirst(BytesTrie trie, StringAndValue[] data, int dataLength) { for (int i = 0; i < dataLength; ++i) { if (data[i].s.Length == 0) { continue; // skip empty string } int c = data[i].bytes[0]; Result firstResult = trie.First(c); int firstValue = firstResult.HasValue() ? trie.GetValue() : -1; int nextC = data[i].s.Length > 1 ? data[i].bytes[1] : 0; Result nextResult = trie.Next(nextC); if (firstResult != trie.Reset().Next(c) || firstResult != trie.Current || firstValue != (firstResult.HasValue() ? trie.GetValue() : -1) || nextResult != trie.Next(nextC) ) { Errln(string.Format("trie.First({0})!=trie.Reset().Next(same) for {1}", (char)c, data[i].s)); } } trie.Reset(); }
private void checkData(StringAndValue[] data, int dataLength, TrieBuilderOption buildOption) { BytesTrie trie = buildTrie(data, dataLength, buildOption); checkFirst(trie, data, dataLength); checkNext(trie, data, dataLength); checkNextWithState(trie, data, dataLength); checkNextString(trie, data, dataLength); checkIterator(trie, data, dataLength); }
private BytesTrie buildTrie(StringAndValue[] data, int dataLength, TrieBuilderOption buildOption) { // Add the items to the trie builder in an interesting (not trivial, not random) order. int index, step; if ((dataLength & 1) != 0) { // Odd number of items. index = dataLength / 2; step = 2; } else if ((dataLength % 3) != 0) { // Not a multiple of 3. index = dataLength / 5; step = 3; } else { index = dataLength - 1; step = -1; } builder_.Clear(); for (int i = 0; i < dataLength; ++i) { builder_.Add(data[index].bytes, data[index].bytes.Length, data[index].value); index = (index + step) % dataLength; } BytesTrie trie = builder_.Build(buildOption); try { builder_.Add(/* "zzz" */ new byte[] { 0x7a, 0x7a, 0x7a }, 0, 999); Errln("builder.build().add(zzz) did not throw InvalidOperationException"); } catch (InvalidOperationException e) { // good } ByteBuffer trieBytes = builder_.BuildByteBuffer(buildOption); Logln("serialized trie size: " + trieBytes.Remaining + " bytes\n"); // Tries from either build() method should be identical but // BytesTrie does not implement equals(). // We just return either one. if ((dataLength & 1) != 0) { return(trie); } else { return(new BytesTrie(trieBytes.Array, trieBytes.ArrayOffset + trieBytes.Position)); } }
public void PutAndGetKeyValue() { BytesTrie trie = new BytesTrie(); var trie2 = trie.Put("012", new byte[] { 1, 2, 3 }); Assert.IsNotNull(trie2); Assert.AreNotSame(trie2, trie); Assert.IsNull(trie.Get("012")); Assert.IsTrue((new byte[] { 1, 2, 3 }).SequenceEqual(trie2.Get("012"))); }
public override int Matches(CharacterIterator text_, int maxLength, int[] lengths, int[] count_, int limit, int[] values) { UCharacterIterator text = UCharacterIterator.GetInstance(text_); BytesTrie bt = new BytesTrie(characters, 0); int c = text.NextCodePoint(); if (c == UCharacterIterator.DONE) { return(0); } Result result = bt.First(Transform(c)); // TODO: should numChars count Character.charCount() ? int numChars = 1; int count = 0; for (; ;) { if (result.HasValue()) { if (count < limit) { if (values != null) { values[count] = bt.GetValue(); } lengths[count] = numChars; count++; } if (result == Result.FinalValue) { break; } } else if (result == Result.NoMatch) { break; } if (numChars >= maxLength) { break; } c = text.NextCodePoint(); if (c == UCharacterIterator.DONE) { break; } ++numChars; result = bt.Next(Transform(c)); } count_[0] = count; return(numChars); }
public void Test41GetNextBytes() { BytesTrie trie = buildMonthsTrie(TrieBuilderOption.Small); StringBuilder buffer = new StringBuilder(); int count = trie.GetNextBytes(buffer); if (count != 2 || !"aj".ContentEquals(buffer)) { Errln("months getNextBytes()!=[aj] at root"); } trie.Next('j'); trie.Next('a'); trie.Next('n'); // getNextBytes() directly after next() buffer.Length = (0); count = trie.GetNextBytes(buffer); if (count != 20 || !".abcdefghijklmnopqru".ContentEquals(buffer)) { Errln("months getNextBytes()!=[.abcdefghijklmnopqru] after \"jan\""); } // getNextBytes() after getValue() trie.GetValue(); // next() had returned BytesTrieResult.INTERMEDIATE_VALUE. buffer.Length = (0); count = trie.GetNextBytes(buffer); if (count != 20 || !".abcdefghijklmnopqru".ContentEquals(buffer)) { Errln("months getNextBytes()!=[.abcdefghijklmnopqru] after \"jan\"+getValue()"); } // getNextBytes() from a linear-match node trie.Next('u'); buffer.Length = (0); count = trie.GetNextBytes(buffer); if (count != 1 || !"a".ContentEquals(buffer)) { Errln("months getNextBytes()!=[a] after \"janu\""); } trie.Next('a'); buffer.Length = (0); count = trie.GetNextBytes(buffer); if (count != 1 || !"r".ContentEquals(buffer)) { Errln("months getNextBytes()!=[r] after \"janua\""); } trie.Next('r'); trie.Next('y'); // getNextBytes() after a final match buffer.Length = (0); count = trie.GetNextBytes(buffer); if (count != 0 || buffer.Length != 0) { Errln("months getNextBytes()!=[] after \"january\""); } }
private int GetPropertyOrValueEnum(int bytesTrieOffset, ICharSequence alias) { BytesTrie trie = new BytesTrie(bytesTries, bytesTrieOffset); if (ContainsName(trie, alias)) { return(trie.GetValue()); } else { #pragma warning disable 612, 618 return((int)UProperty.Undefined); #pragma warning restore 612, 618 } }
public void ReplaceValue() { BytesTrie trie = new BytesTrie(); var trie2 = trie.Put("012", new byte[] { 1, 2, 3 }); var trie3 = trie2.Put("012", new byte[] { 4, 5, 6 }); Assert.IsNotNull(trie2); Assert.AreNotSame(trie2, trie); Assert.IsNull(trie.Get("012")); Assert.IsTrue((new byte[] { 1, 2, 3 }).SequenceEqual(trie2.Get("012"))); Assert.IsNotNull(trie3); Assert.AreNotSame(trie3, trie2); Assert.IsTrue((new byte[] { 4, 5, 6 }).SequenceEqual(trie3.Get("012"))); }
public void Test50IteratorFromBranch() { BytesTrie trie = buildMonthsTrie(TrieBuilderOption.Fast); // Go to a branch node. trie.Next('j'); trie.Next('a'); trie.Next('n'); BytesTrieEnumerator iter = (BytesTrieEnumerator)trie.GetEnumerator(); // Expected data: Same as in buildMonthsTrie(), except only the suffixes // following "jan". StringAndValue[] data = { new StringAndValue("", 1), new StringAndValue(".", 1), new StringAndValue("a", 1), new StringAndValue("bb", 1), new StringAndValue("c", 1), new StringAndValue("ddd", 1), new StringAndValue("ee", 1), new StringAndValue("ef", 1), new StringAndValue("f", 1), new StringAndValue("gg", 1), new StringAndValue("h", 1), new StringAndValue("iiii", 1), new StringAndValue("j", 1), new StringAndValue("kk", 1), new StringAndValue("kl", 1), new StringAndValue("kmm", 1), new StringAndValue("l", 1), new StringAndValue("m", 1), new StringAndValue("nnnnnnnnnnnnnnnnnnnnnnnnnnnn", 1), new StringAndValue("o", 1), new StringAndValue("pp", 1), new StringAndValue("qqq", 1), new StringAndValue("r", 1), new StringAndValue("uar", 1), new StringAndValue("uary", 1) }; checkIterator(iter, data); // Reset, and we should get the same result. Logln("after iter.Reset()"); checkIterator(iter.Reset(), data); }
public void Test59IteratorFromBytes() { StringAndValue[] data = { new StringAndValue("mm", 3), new StringAndValue("mmm", 33), new StringAndValue("mmnop", 333) }; builder_.Clear(); foreach (StringAndValue item in data) { builder_.Add(item.bytes, item.bytes.Length, item.value); } ByteBuffer trieBytes = builder_.BuildByteBuffer(TrieBuilderOption.Fast); checkIterator( BytesTrie.GetEnumerator(trieBytes.Array, trieBytes.ArrayOffset + trieBytes.Position, 0), data); }
// next(string) is also tested in other functions, // but here we try to go partway through the string, and then beyond it. private void checkNextString(BytesTrie trie, StringAndValue[] data, int dataLength) { for (int i = 0; i < dataLength; ++i) { byte[] expectedString = data[i].bytes; int stringLength = data[i].s.Length; if (!trie.Next(expectedString, 0, stringLength / 2).Matches()) { Errln("trie.Next(up to middle of string)=BytesTrieResult.NO_MATCH for " + data[i].s); continue; } // Test that we stop properly at the end of the string. trie.Next(expectedString, stringLength / 2, stringLength); if (trie.Next(0).Matches()) { Errln("trie.Next(string+NUL)!=BytesTrieResult.NO_MATCH for " + data[i].s); } trie.Reset(); } }
public void Test52TruncatingIteratorFromRoot() { BytesTrie trie = buildMonthsTrie(TrieBuilderOption.Fast); BytesTrieEnumerator iter = trie.GetEnumerator(4); // Expected data: Same as in buildMonthsTrie(), except only the first 4 characters // of each string, and no string duplicates from the truncation. StringAndValue[] data = { new StringAndValue("augu", -1), new StringAndValue("jan", 1), new StringAndValue("jan.", 1), new StringAndValue("jana", 1), new StringAndValue("janb", -1), new StringAndValue("janc", 1), new StringAndValue("jand", -1), new StringAndValue("jane", -1), new StringAndValue("janf", 1), new StringAndValue("jang", -1), new StringAndValue("janh", 1), new StringAndValue("jani", -1), new StringAndValue("janj", 1), new StringAndValue("jank", -1), new StringAndValue("janl", 1), new StringAndValue("janm", 1), new StringAndValue("jann", -1), new StringAndValue("jano", 1), new StringAndValue("janp", -1), new StringAndValue("janq", -1), new StringAndValue("janr", 1), new StringAndValue("janu", -1), new StringAndValue("july", 7), new StringAndValue("jun", 6), new StringAndValue("jun.", 6), new StringAndValue("june", 6) }; checkIterator(iter, data); // Reset, and we should get the same result. Logln("after iter.Reset()"); checkIterator(iter.Reset(), data); }
private bool ContainsName(BytesTrie trie, ICharSequence name) { Result result = Result.NoValue; for (int i = 0; i < name.Length; ++i) { int c = name[i]; // Ignore delimiters '-', '_', and ASCII White_Space. if (c == '-' || c == '_' || c == ' ' || (0x09 <= c && c <= 0x0d)) { continue; } if (!result.HasNext()) { return(false); } c = AsciiToLowercase(c); result = trie.Next(c); } return(result.HasValue()); }
public void Test40GetUniqueValue() { BytesTrie trie = buildMonthsTrie(TrieBuilderOption.Fast); long uniqueValue; if ((uniqueValue = trie.GetUniqueValue()) != 0) { Errln("unique value at root"); } trie.Next('j'); trie.Next('a'); trie.Next('n'); // getUniqueValue() directly after next() if ((uniqueValue = trie.GetUniqueValue()) != ((1 << 1) | 1)) { Errln("not unique value 1 after \"jan\": instead " + uniqueValue); } trie.First('j'); trie.Next('u'); if ((uniqueValue = trie.GetUniqueValue()) != 0) { Errln("unique value after \"ju\""); } if (trie.Next('n') != Result.IntermediateValue || 6 != trie.GetValue()) { Errln("not normal value 6 after \"jun\""); } // getUniqueValue() after getValue() if ((uniqueValue = trie.GetUniqueValue()) != ((6 << 1) | 1)) { Errln("not unique value 6 after \"jun\""); } // getUniqueValue() from within a linear-match node trie.First('a'); trie.Next('u'); if ((uniqueValue = trie.GetUniqueValue()) != ((8 << 1) | 1)) { Errln("not unique value 8 after \"au\""); } }
public void Test51IteratorFromLinearMatch() { BytesTrie trie = buildMonthsTrie(StringTrieBuilder.Option.SMALL); // Go into a linear-match node. trie.Next('j'); trie.Next('a'); trie.Next('n'); trie.Next('u'); trie.Next('a'); BytesTrie.Enumerator iter = trie.GetEnumerator(); // Expected data: Same as in buildMonthsTrie(), except only the suffixes // following "janua". StringAndValue[] data = { new StringAndValue("r", 1), new StringAndValue("ry", 1) }; checkIterator(iter, data); // Reset, and we should get the same result. Logln("after iter.Reset()"); checkIterator(iter.Reset(), data); }
private void checkNextWithState(BytesTrie trie, StringAndValue[] data, int dataLength) { BytesTrieState noState = new BytesTrieState(), state = new BytesTrieState(); for (int i = 0; i < dataLength; ++i) { if ((i & 1) == 0) { try { trie.ResetToState(noState); Errln("trie.ResetToState(noState) should throw an ArgumentException"); } catch (ArgumentException e) { // good } } byte[] expectedString = data[i].bytes; int stringLength = data[i].s.Length; int partialLength = stringLength / 3; for (int j = 0; j < partialLength; ++j) { if (!trie.Next(expectedString[j]).Matches()) { Errln("trie.Next()=BytesTrieResult.NO_MATCH for a prefix of " + data[i].s); return; } } trie.SaveState(state); Result resultAtState = trie.Current; Result result; int valueAtState = -99; if (resultAtState.HasValue()) { valueAtState = trie.GetValue(); } result = trie.Next(0); // mismatch if (result != Result.NoMatch || result != trie.Current) { Errln("trie.Next(0) matched after part of " + data[i].s); } if (resultAtState != trie.ResetToState(state).Current || (resultAtState.HasValue() && valueAtState != trie.GetValue()) ) { Errln("trie.Next(part of " + data[i].s + ") changes current()/getValue() after " + "saveState/next(0)/resetToState"); } else if (!(result = trie.Next(expectedString, partialLength, stringLength)).HasValue() || result != trie.Current) { Errln("trie.Next(rest of " + data[i].s + ") does not seem to contain " + data[i].s + " after " + "saveState/next(0)/resetToState"); } else if (!(result = trie.ResetToState(state). Next(expectedString, partialLength, stringLength)).HasValue() || result != trie.Current) { Errln("trie does not seem to contain " + data[i].s + " after saveState/next(rest)/resetToState"); } else if (trie.GetValue() != data[i].value) { Errln(String.Format("trie value for {0} is {1:d}=0x{2:x} instead of expected {3:d}=0x{4:x}", data[i].s, trie.GetValue(), trie.GetValue(), data[i].value, data[i].value)); } trie.Reset(); } }
private void checkNext(BytesTrie trie, StringAndValue[] data, int dataLength) { BytesTrieState state = new BytesTrieState(); for (int i = 0; i < dataLength; ++i) { int stringLength = data[i].s.Length; Result result; if (!(result = trie.Next(data[i].bytes, 0, stringLength)).HasValue() || result != trie.Current ) { Errln("trie does not seem to contain " + data[i].s); } else if (trie.GetValue() != data[i].value) { Errln(string.Format("trie value for {0} is {1:d}=0x{2:x} instead of expected {3:d}=0x{4:x}", data[i].s, trie.GetValue(), trie.GetValue(), data[i].value, data[i].value)); } else if (result != trie.Current || trie.GetValue() != data[i].value) { Errln("trie value for " + data[i].s + " changes when repeating current()/getValue()"); } trie.Reset(); result = trie.Current; for (int j = 0; j < stringLength; ++j) { if (!result.HasNext()) { Errln(String.Format("trie.Current!=hasNext before end of {0} (at index {1:d})", data[i].s, j)); break; } if (result == Result.IntermediateValue) { trie.GetValue(); if (trie.Current != Result.IntermediateValue) { Errln(String.Format("trie.GetValue().Current!=BytesTrieResult.INTERMEDIATE_VALUE " + "before end of {0} (at index {1:d})", data[i].s, j)); break; } } result = trie.Next(data[i].bytes[j]); if (!result.Matches()) { Errln(String.Format("trie.Next()=BytesTrieResult.NO_MATCH " + "before end of {0} (at index {1:d})", data[i].s, j)); break; } if (result != trie.Current) { Errln(String.Format("trie.Next()!=following current() " + "before end of {0} (at index {1:d})", data[i].s, j)); break; } } if (!result.HasValue()) { Errln("trie.Next()!=hasValue at the end of " + data[i].s); continue; } trie.GetValue(); if (result != trie.Current) { Errln("trie.Current != current()+getValue()+current() after end of " + data[i].s); } // Compare the final current() with whether next() can actually continue. trie.SaveState(state); bool nextContinues = false; for (int c = 0x20; c < 0x7f; ++c) { if (trie.ResetToState(state).Next(c).Matches()) { nextContinues = true; break; } } if ((result == Result.IntermediateValue) != nextContinues) { Errln("(trie.Current==BytesTrieResult.INTERMEDIATE_VALUE) contradicts " + "(trie.Next(some UChar)!=BytesTrieResult.NO_MATCH) after end of " + data[i].s); } trie.Reset(); } }
private void checkIterator(BytesTrie trie, StringAndValue[] data, int dataLength) { checkIterator(trie.GetEnumerator(), data, dataLength); }
public void GetUnknowKey() { BytesTrie trie = new BytesTrie(); Assert.IsNull(trie.Get("012")); }