public LTrieKid GetKid(int kid) { LTrieKid kidDef = new LTrieKid(); //Check if it's used somewhere kidDef.Val = kid; kid++; //bringing kid to the real value int kidPlace = kid * shift; if (_f[kidPlace] == 1) { kidDef.Exists = true; if (_f[kidPlace + 1] == 1) { kidDef.LinkToNode = false; //Link to Value } kidDef.Ptr = new byte[DefaultPointerLength]; Buffer.BlockCopy(_f, (kidPlace + 2), kidDef.Ptr, 0, DefaultPointerLength); //for (int i = 0; i < DefaultPointerLength; i++) //Can be changed on substring //{ // kidDef.Ptr[i] = _f[(kidPlace + 2) + i]; //} } return(kidDef); }
public IEnumerable <LTrieKid> GetKidsBackward(int startFrom) { LTrieKid ret = null; if (this.count > 0 && startFrom != 256) { startFrom += 1; int kidPlace = 0; for (int i = startFrom; i > 0; i--) { kidPlace = i * shift; if (_f[kidPlace] == 1) { ret = new LTrieKid(); ret.Exists = true; ret.Val = i - 1; ret.Ptr = new byte[DefaultPointerLength]; for (int j = 0; j < DefaultPointerLength; j++) //Can be changed on substring { ret.Ptr[j] = _f[(kidPlace + 2) + j]; } //Setting up link to Node or to Value if (_f[kidPlace + 1] == 1) { ret.LinkToNode = false; } yield return(ret); } } } if (!ValueIsEmpty) { ret = new LTrieKid(); //trying to take max kid ret.Ptr = PtrToValue; ret.Exists = true; ret.ValueKid = true; ret.Val = 256; yield return(ret); } }
/// <summary> /// Gets Value kid (before 0-255) /// </summary> /// <returns></returns> public LTrieKid GetKidValue() { LTrieKid kidDef = new LTrieKid(); kidDef.ValueKid = true; if (ValueIsEmpty) { return(kidDef); } kidDef.Exists = true; kidDef.Val = 256; kidDef.Ptr = PtrToValue; return(kidDef); }
public LTrieKid GetMinKid() { LTrieKid ret = new LTrieKid(); if (!ValueIsEmpty) { //In case if we have value then it's a minimum ret.Ptr = PtrToValue; ret.Exists = true; ret.ValueKid = true; ret.Val = 256; } else { SearchExtremums(); if (MinKidNull) { return(ret); } int kidPlace = MinKid * shift; ret.Exists = true; ret.Val = MinKid - 1; //Bringing value to [0-255] //Copying Pointer ret.Ptr = new byte[DefaultPointerLength]; for (int i = 0; i < DefaultPointerLength; i++) //Can be changed on substring { ret.Ptr[i] = _f[(kidPlace + 2) + i]; } //Setting up link to Node or to Value if (_f[kidPlace + 1] == 1) { ret.LinkToNode = false; } } return(ret); }
//public LTrieKid GetKidBiggerThen(int kid) //{ // LTrieKid ret = new LTrieKid(); // kid += 2; // if (kid > 256) // return ret; // int kidPlace = 0; // for (int i = kid; i <= 256; i++) //i<257 // { // kidPlace = i * shift; // if (_f[kidPlace] == 1) // { // ret.Exists = true; // ret.Val = i - 1; // ret.Ptr = new byte[DefaultPointerLength]; // for (int j = 0; j < DefaultPointerLength; j++) //Can be changed on substring // { // ret.Ptr[j] = _f[(kidPlace + 2) + j]; // } // //Setting up link to Node or to Value // if (_f[kidPlace + 1] == 1) // ret.LinkToNode = false; // return ret; // } // } // return ret; //} public IEnumerable <LTrieKid> GetKidsForward(int startFrom) { LTrieKid ret = null; //USE it later if startFrom = 256 if (startFrom == 256) { if (!ValueIsEmpty) { ret = new LTrieKid(); //trying to take max kid ret.Ptr = PtrToValue; ret.Exists = true; ret.ValueKid = true; ret.Val = 256; yield return(ret); } startFrom = 0; } if (this.count > 0) { //Change back kid to normal startFrom += 1; //if (startFrom == 256) // startFrom = 1; //else // startFrom += 1; int kidPlace = 0; for (int i = startFrom; i <= 256; i++) { kidPlace = i * shift; if (_f[kidPlace] == 1) { ret = new LTrieKid(); ret.Exists = true; ret.Val = i - 1; ret.Ptr = new byte[DefaultPointerLength]; for (int j = 0; j < DefaultPointerLength; j++) //Can be changed on substring { ret.Ptr[j] = _f[(kidPlace + 2) + j]; } //Setting up link to Node or to Value if (_f[kidPlace + 1] == 1) { ret.LinkToNode = false; } yield return(ret); } } } }
//#region "Checking Of Empty Pointer" ///// <summary> ///// Checks if pointer is empty ///// </summary> ///// <param name="ptr"></param> ///// <returns></returns> //public bool _IfPointerIsEmpty(byte[] ptr) //{ // //Executes 52 ms // #region "Settign up delegate" // switch (this.DefaultPointerLen) // { // case 5: //Gives ability to allocate file up to 1 terrabyte (1.099.511.627.775) // return !( // ptr[4] != 0 // || // ptr[3] != 0 // || // ptr[2] != 0 // || // ptr[1] != 0 // || // ptr[0] != 0 // ); // case 4: //4GB // return !( // ptr[3] != 0 // || // ptr[2] != 0 // || // ptr[1] != 0 // || // ptr[0] != 0 // ); // case 3: //17MB // return !( // ptr[2] != 0 // || // ptr[1] != 0 // || // ptr[0] != 0 // ); // case 6: //281 Terrabytes (281.474.976.710.655) // return !( // ptr[5] != 0 // || // ptr[4] != 0 // || // ptr[3] != 0 // || // ptr[2] != 0 // || // ptr[1] != 0 // || // ptr[0] != 0 // ); // case 7: //72 Petabytes (72.057.594.037.927.935) // return !( // ptr[6] != 0 // || // ptr[5] != 0 // || // ptr[4] != 0 // || // ptr[3] != 0 // || // ptr[2] != 0 // || // ptr[1] != 0 // || // ptr[0] != 0 // ); // case 2: //65 KB // return !( // ptr[1] != 0 // || // ptr[0] != 0 // ); // default: // return ptr._ByteArrayEquals(this.EmptyPointer); // } // #endregion //} //#endregion #region "DATA FETCHING" /// <summary> /// /// </summary> /// <param name="key"></param> /// <param name="useCache"></param> /// <param name="ValuesLazyLoadingIsOn">if true reads key only</param> /// <returns></returns> public LTrieRow GetKey(byte[] key, bool useCache, bool ValuesLazyLoadingIsOn) { LTrieRow kv = new LTrieRow(this); kv.Key = key; //if (key == null || key.Length == 0) // return kv; if (key == null) { return(kv); } LTrieGenerationNode gn = null; if (_generationMap.Count() == 0) { //Loading it from Link TO ZERO Pointer gn = new LTrieGenerationNode(this); gn.Pointer = this.LinkToZeroNode; //gn.Value=0; - default _generationMap.Add(0, gn); gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0)); //gn.ReadSelf(); } bool cleanCheck = true; LTrieKid kidDef = null; int p = 0; int len = key.Length; /*SPECIAL CASE key = byte[0]*/ if (key.Length == 0) { kidDef = _generationMap[0].GetKidAsValue(true, 1); if (kidDef.Exists) { kv.LinkToValue = kidDef.Ptr; } return(kv); } /****************************/ for (int i = 0; i < len; i++) { //Getting kid from actual generation map if (cleanCheck && i != 0 && _generationMap.ContainsKey(i) && _generationMap[i].Value != key[i - 1]) { cleanCheck = false; _generationMap.RemoveBiggerOrEqualThenKey(i); } if (!_generationMap.ContainsKey(i)) { gn = new LTrieGenerationNode(this); gn.Value = key[i - 1]; gn.Pointer = _generationMap[i - 1].KidsInNode.GetPointerToTheKid(key[i - 1]); //FIND A SOLUTION FOR THIS NULL or EMPTY POINTER //if (gn.Pointer == null || this._IfPointerIsEmpty(gn.Pointer)) // return kv; if (gn.Pointer == null || gn.Pointer._IfPointerIsEmpty(this.DefaultPointerLen)) { return(kv); } _generationMap.Add(i, gn); gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(i)); //gn.ReadSelf(); } //Also if last element then supply 256 to get value not the link to value (if no value exit) //If kid is a link to next node we iterate further, if link on the value, we retrieve full key and value as link for TreeKVP stoping iteration //If link is empty (no kid) we return empty if (i >= key.Length) { p = i - 1; } else { p = i; } kidDef = _generationMap[i].GetKidAsValue((i >= (key.Length)), key[p]); if (kidDef.Exists) { if (kidDef.ValueKid) { kv.LinkToValue = kidDef.Ptr; return(kv); } if (!kidDef.LinkToNode) { //byte[] storedKey = _generationMap[i].ReadKidKeyFromValPtr(kidDef.Ptr); long valueStartPtr = 0; uint valueLength = 0; byte[] xValue = null; byte[] storedKey = null; if (!ValuesLazyLoadingIsOn) { this.Tree.Cache.ReadKeyValue(useCache, kidDef.Ptr, out valueStartPtr, out valueLength, out storedKey, out xValue); } else { storedKey = this.Tree.Cache.ReadKey(useCache, kidDef.Ptr); } // byte[] storedKey = this.Tree.Cache.ReadKey(useCache, kidDef.Ptr); if (key.Length != storedKey.Length || !key._ByteArrayEquals(storedKey)) { return(kv); } if (!ValuesLazyLoadingIsOn) { kv.ValueStartPointer = valueStartPtr; kv.ValueFullLength = valueLength; kv.Value = xValue; kv.ValueIsReadOut = true; } kv.LinkToValue = kidDef.Ptr; return(kv); } if (i == key.Length - 1) { len++; } //iterating further } else { return(kv); } } return(kv); }