public AutomataNode SearchNextSafe(byte[] p, ref int offset, ref int rest) { var key = AutomataKeyGen.GetKeySafe(p, ref offset, ref rest); if (count < 4) { // linear search for (int i = 0; i < count; i++) { if (nextKeys[i] == key) { return(nexts[i]); } } } else { // binary search var index = BinarySearch(nextKeys, 0, count, key); if (index >= 0) { return(nexts[index]); } } return(null); }
public unsafe void Add(string str, int value) { var bytes = Encoding.UTF8.GetBytes(str); fixed(byte *buffer = &bytes[0]) { var node = root; var p = buffer; var rest = bytes.Length; while (rest != 0) { var key = AutomataKeyGen.GetKey(ref p, ref rest); if (rest == 0) { node = node.Add(key, value, str); } else { node = node.Add(key); } } } }
// SearchNext(ref byte* p, ref int rest, ref ulong key) public void EmitSearchNext(ILGenerator il, LocalBuilder p, LocalBuilder rest, LocalBuilder key, Action <KeyValuePair <string, int> > onFound, Action onNotFound) { // key = AutomataKeyGen.GetKey(ref p, ref rest); il.EmitLdloca(p); il.EmitLdloca(rest); #if NETSTANDARD || NETFRAMEWORK il.EmitCall(AutomataKeyGen.GetKeyMethod); #else il.EmitCall(AutomataKeyGen.GetGetKeyMethod()); #endif il.EmitStloc(key); // match children. EmitSearchNextCore(il, p, rest, key, onFound, onNotFound, nexts, count); }
// for Unity, use safe only. public void Add(string str, int value) { var bytes = Encoding.UTF8.GetBytes(str); var offset = 0; var node = root; var rest = bytes.Length; while (rest != 0) { var key = AutomataKeyGen.GetKeySafe(bytes, ref offset, ref rest); if (rest == 0) { node = node.Add(key, value, str); } else { node = node.Add(key); } } }