public IEnumerable<LTrieRow> IterateBackwardStartsWith(byte[] initKey, bool useCache) { if (initKey.Length < 1) yield break; LTrieGenerationNode gn = null; initialKey = initKey; LTrieGenerationMap _generationMap = new LTrieGenerationMap(); //_generationMap.Clear(); //if (_generationMap.Count() == 0) //{ //Loading it from Link TO ZERO Pointer gn = new LTrieGenerationNode(this._root); gn.Pointer = this._root.LinkToZeroNode; //gn.Value=0; - default _generationMap.Add(0, gn); gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0)); //} //ulong cnt = 0; byte[] generationMapLine = new byte[1] { 0 }; byte[] gml = null; LTrieGenerationNode gn1 = null; byte[] key = null; LTrieRow row = null; //bool kFnd = false; foreach (var kd in gn.KidsInNode.GetKidsBackward(initialKey[0])) { //For first linke only if (kd.Val != initKey[0]) continue; //Kid can be value link or node link //if value link we can count 1 up if (kd.ValueKid || !kd.LinkToNode) { key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr); //Console.WriteLine("KN: {0}", key.ToBytesString("")); if (key.IfStringArrayStartsWith(initialKey)) { //cnt++; row = new LTrieRow(this._root); row.Key = key; row.LinkToValue = kd.Ptr; yield return row; } } else { gn1 = new LTrieGenerationNode(this._root); gn1.Pointer = kd.Ptr; gn1.Value = (byte)kd.Val; gml = generationMapLine.Concat(gn1.Value); gn1.ReadSelf(useCache, gml); //generationMapLine = generationMapLine.Concat(gn1.Value); //gn1.ReadSelf(useCache, generationMapLine); //foreach (var xr in ItBwdStartsWith(gn1, generationMapLine, 1, true, useCache)) foreach (var xr in ItBwdStartsWith(gn1, gml, 1, useCache)) { //cnt++; yield return xr; } } } //Console.WriteLine("CNT: {0}", cnt); }
public IEnumerable<LTrieRow> IterateBackwardStartFrom(byte[] initKey, bool inclStartKey, bool useCache) { LTrieGenerationNode gn = null; initialKey = initKey; includeStartKey = inclStartKey; LTrieGenerationMap _generationMap = new LTrieGenerationMap(); //if (_generationMap.Count() == 0) //{ //Loading it from Link TO ZERO Pointer gn = new LTrieGenerationNode(this._root); gn.Pointer = this._root.LinkToZeroNode; //gn.Value=0; - default _generationMap.Add(0, gn); gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0)); //} //ulong cnt = 0; //NEED ONLY FOR SKIP byte[] generationMapLine = new byte[1] { 0 }; byte[] gml = null; LTrieGenerationNode gn1 = null; byte[] key = null; LTrieRow row = null; long valueStartPtr = 0; uint valueLength = 0; byte[] xValue = null; //Starting from first key. It's interesting inside of RecursiveYieldReturn to look Starting from value //If intialKey index already bigger then its own length //But for the first must be enough foreach (var kd in gn.KidsInNode.GetKidsBackward(initialKey[0])) { //Console.WriteLine("KN: {0}", key.ToBytesString("")); //Kid can be value link or node link //if value link we can count 1 up if (kd.ValueKid || !kd.LinkToNode) { if (keyIsFound) { //We return this one key //cnt++; row = new LTrieRow(this._root); if (ReturnKeyValuePair) { this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue); row.ValueStartPointer = valueStartPtr; row.ValueFullLength = valueLength; row.Value = xValue; row.ValueIsReadOut = true; } else { key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr); } row.Key = key; row.LinkToValue = kd.Ptr; yield return row; } else { if (ReturnKeyValuePair) { this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue); } else { key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr); } //Checking if key equals to the found element, bigger or smaller //Key is still not found if ((includeStartKey) ? key.IfStringArraySmallerOrEqualThen(initialKey) : key.IfStringArraySmallerThen(initialKey)) //if(key.IfStringArraySmallerThen(initialKey)) //if (IfFirstKeyIsSmallerThenCompareKey(key, initialKey)) { keyIsFound = true; //We return this one key //We dont apply reading key with value here, using LazyLoading //cnt++; row = new LTrieRow(this._root); if (ReturnKeyValuePair) { row.ValueStartPointer = valueStartPtr; row.ValueFullLength = valueLength; row.Value = xValue; row.ValueIsReadOut = true; } row.Key = key; row.LinkToValue = kd.Ptr; yield return row; //going on iteration } } } else { if (!keyIsFound && initialKey[0] > kd.Val) keyIsFound = true; gn1 = new LTrieGenerationNode(this._root); gn1.Pointer = kd.Ptr; gn1.Value = (byte)kd.Val; //increasing map line must hold already 2 elements gml = generationMapLine.Concat(gn1.Value); gn1.ReadSelf(useCache, gml); //generationMapLine = generationMapLine.Concat(gn1.Value); //gn1.ReadSelf(useCache, generationMapLine); //foreach (var xr in ItBwdStartFrom(gn1, generationMapLine, useCache)) foreach (var xr in ItBwdStartFrom(gn1, gml, useCache)) { //cnt++; //NEED ONLY FOR SKIP yield return xr; } } } //Console.WriteLine("CNT: {0}", cnt); }
public IEnumerable<LTrieRow> IterateBackward(bool useCache) { LTrieGenerationNode gn = null; LTrieGenerationMap _generationMap = new LTrieGenerationMap(); //_generationMap.Clear(); //if (_generationMap.Count() == 0) //{ //Loading it from Link TO ZERO Pointer gn = new LTrieGenerationNode(this._root); gn.Pointer = this._root.LinkToZeroNode; //gn.Value=0; - default _generationMap.Add(0, gn); gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0)); //} //ulong cnt = 0; byte[] generationMapLine = new byte[1] { 0 }; byte[] gml = null; LTrieGenerationNode gn1 = null; byte[] key = null; LTrieRow row = null; long valueStartPtr = 0; uint valueLength = 0; byte[] xValue = null; foreach (var kd in gn.KidsInNode.GetKidsBackward()) { //Kid can be value link or node link //if value link we can count 1 up if (kd.ValueKid || !kd.LinkToNode) { //Console.WriteLine("KN: {0}", key.ToBytesString("")); //cnt++; row = new LTrieRow(this._root); if (ReturnKeyValuePair) { this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue); row.ValueStartPointer = valueStartPtr; row.ValueFullLength = valueLength; row.Value = xValue; row.ValueIsReadOut = true; } else { key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr); } row.Key = key; row.LinkToValue = kd.Ptr; yield return row; } else { gn1 = new LTrieGenerationNode(this._root); gn1.Pointer = kd.Ptr; gn1.Value = (byte)kd.Val; gml = generationMapLine.Concat(gn1.Value); gn1.ReadSelf(useCache, gml); //generationMapLine = generationMapLine.Concat(gn1.Value); //gn1.ReadSelf(useCache, generationMapLine); //foreach (var xr in ItBwd(gn1, generationMapLine, useCache)) foreach (var xr in ItBwd(gn1, gml, useCache)) { //cnt++; yield return xr; } } } //Console.WriteLine("CNT: {0}", cnt); }
public void IterateForwardStartsWith_Prefix_Helper(byte[] initKey, bool useCache) { LTrieGenerationNode gn = null; initialKey = initKey; LTrieGenerationMap _generationMap = new LTrieGenerationMap(); //Loading it from Link TO ZERO Pointer gn = new LTrieGenerationNode(this._root); gn.Pointer = this._root.LinkToZeroNode; _generationMap.Add(0, gn); gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0)); byte[] generationMapLine = new byte[1] { 0 }; byte[] gml = null; LTrieGenerationNode gn1 = null; byte[] key = null; LTrieRow row = null; //Starting from first key. It's interesting inside of RecursiveYieldReturn to look Starting from value //If intialKey index already bigger then its own length //But for the first must be enough foreach (var kd in gn.KidsInNode.GetKidsForward(initialKey[0])) { if (kd.Val != initKey[0]) continue; //Console.WriteLine(System.Text.Encoding.ASCII.GetString(new byte[] {initKey[0]})); //Kid can be value link or node link //if value link we can count 1 up if (kd.ValueKid || !kd.LinkToNode) { PrefixDeep++; //key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr); //if (key[0] == initialKey[0]) // lstClosestPrefix.Add(initialKey[0]); } else { gn1 = new LTrieGenerationNode(this._root); gn1.Pointer = kd.Ptr; gn1.Value = (byte)kd.Val; //increasing map line must hold already 2 elements gml = generationMapLine.Concat(gn1.Value); gn1.ReadSelf(useCache, gml); PrefixDeep++; foreach (var xr in ItFrwStartsWith_Prefix_Helper(gn1, gml, 1, useCache)) { //we must iterate to fill lstClosestPrefix } } } }
public IEnumerable<LTrieRow> IterateForwardStartsWith(byte[] initKey, bool useCache) { if (initKey.Length < 1) yield break; LTrieGenerationNode gn = null; initialKey = initKey; LTrieGenerationMap _generationMap = new LTrieGenerationMap(); //if (_generationMap.Count() == 0) //{ //Loading it from Link TO ZERO Pointer gn = new LTrieGenerationNode(this._root); gn.Pointer = this._root.LinkToZeroNode; //gn.Value=0; - default _generationMap.Add(0, gn); gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0)); //} //ulong cnt = 0; //NEED ONLY FOR SKIP byte[] generationMapLine = new byte[1] { 0 }; byte[] gml = null; LTrieGenerationNode gn1 = null; byte[] key = null; LTrieRow row = null; //Starting from first key. It's interesting inside of RecursiveYieldReturn to look Starting from value //If intialKey index already bigger then its own length //But for the first must be enough foreach (var kd in gn.KidsInNode.GetKidsForward(initialKey[0])) { if (kd.Val != initKey[0]) continue; //Console.WriteLine("KN: {0}", key.ToBytesString("")); //Kid can be value link or node link //if value link we can count 1 up if (kd.ValueKid || !kd.LinkToNode) { key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr); if (key.IfStringArrayStartsWith(initialKey)) { //cnt++; row = new LTrieRow(this._root); row.Key = key; row.LinkToValue = kd.Ptr; yield return row; } } else { gn1 = new LTrieGenerationNode(this._root); gn1.Pointer = kd.Ptr; gn1.Value = (byte)kd.Val; //increasing map line must hold already 2 elements gml = generationMapLine.Concat(gn1.Value); gn1.ReadSelf(useCache, gml); //generationMapLine = generationMapLine.Concat(gn1.Value); //gn1.ReadSelf(useCache, generationMapLine); //foreach (var xr in ItFrwStartsWith(gn1, generationMapLine, 1, true, useCache)) foreach (var xr in ItFrwStartsWith(gn1, gml, 1, useCache)) { yield return xr; } } } //Console.WriteLine("CNT: {0}", cnt); }
public IEnumerable<LTrieRow> IterateForwardSkipFrom(byte[] initKey, ulong skippingQuantity, bool useCache) { LTrieGenerationNode gn = null; initialKey = initKey; skippingTotal = skippingQuantity; LTrieGenerationMap _generationMap = new LTrieGenerationMap(); //if (_generationMap.Count() == 0) //{ //Loading it from Link TO ZERO Pointer gn = new LTrieGenerationNode(this._root); gn.Pointer = this._root.LinkToZeroNode; //gn.Value=0; - default _generationMap.Add(0, gn); gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0)); //} //ulong cnt = 0; //NEED ONLY FOR SKIP byte[] generationMapLine = new byte[1] { 0 }; byte[] gml = null; LTrieGenerationNode gn1 = null; byte[] key = null; LTrieRow row = null; long valueStartPtr = 0; uint valueLength = 0; byte[] xValue = null; //Starting from first key. It's interesting inside of RecursiveYieldReturn to look Starting from value //If intialKey index already bigger then its own length //But for the first must be enough foreach (var kd in gn.KidsInNode.GetKidsForward(initialKey[0])) { //Console.WriteLine("KN: {0}", key.ToBytesString("")); //Kid can be value link or node link //if value link we can count 1 up if (kd.ValueKid || !kd.LinkToNode) { if (keyIsFound) { //We return this one key, if quantity of skips is enough skippedCnt++; if (skippedCnt > skippingTotal) { if (ReturnKeyValuePair) { this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue); } else { key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr); } //cnt++; row = new LTrieRow(this._root); if (ReturnKeyValuePair) { row.ValueStartPointer = valueStartPtr; row.ValueFullLength = valueLength; row.Value = xValue; row.ValueIsReadOut = true; } row.Key = key; row.LinkToValue = kd.Ptr; yield return row; } } else { key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr); //Checking if key equals to the found element, bigger or smaller //Key is still not found if (key.IfStringArrayBiggerOrEqualThen(initialKey)) { keyIsFound = true; //case if Startkey doesn't exist, then first encountered value can be calculated as first for skipping if (key.IfStringArrayBiggerThen(initialKey)) { skippedCnt++; if (skippedCnt > skippingTotal) { //key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr); row = new LTrieRow(this._root); row.Key = key; row.LinkToValue = kd.Ptr; yield return row; } } } } } else { //special case when from key doesn't exist if (initialKey[0] < kd.Val) keyIsFound = true; gn1 = new LTrieGenerationNode(this._root); gn1.Pointer = kd.Ptr; gn1.Value = (byte)kd.Val; //increasing map line must hold already 2 elements gml = generationMapLine.Concat(gn1.Value); gn1.ReadSelf(useCache, gml); //generationMapLine = generationMapLine.Concat(gn1.Value); //gn1.ReadSelf(useCache, generationMapLine); //foreach (var xr in ItFrwSkipFrom(gn1, generationMapLine, useCache)) foreach (var xr in ItFrwSkipFrom(gn1, gml, useCache)) { //cnt++; //NEED ONLY FOR SKIP yield return xr; } } } //Console.WriteLine("CNT: {0}", cnt); }