public int Search(TaskQueue.ValueMap <string, object> key) { int outCmp = 0, idx; IndexSector currentSector = RootGradient; for (int i = 0; i < 1000; i++) { idx = currentSector.BinarySearch(key, out outCmp); IndexElement el = currentSector.IndexElements[idx]; if (currentSector.IsSerial) { return(idx); } else { currentSector = GetSector(el.Reference); } } return(-1); }
public bool Remove(TaskQueue.ValueMap <string, object> key) { int outCmp = 0, idx; IndexSector currentSector = RootGradient; for (int i = 0; i < MAXGRADIENTLEVEL; i++) { idx = currentSector.BinarySearch(key, out outCmp); if (currentSector.IsSerial) { if (outCmp == 0) { // ok we found it, remove it now currentSector.IndexElements.RemoveAt(idx); if (currentSector.IndexElements.Count == 0) { // nothing to do with it, sector remains with references on it in gradients // or we can remove it if storage in-memory... TaskQueue.ValueMap <string, object> newKey = null; IndexSector refSector = currentSector; IndexSector grad = GetSector(currentSector.TopGradientReference); bool elementFound = true, nextElement = false, removeElement = true; while (true) { elementFound = nextElement = false; for (int j = 0; j < grad.IndexElements.Count; j++) { if (grad.IndexElements[j].Reference == refSector.Location) { elementFound = true; if (removeElement) { if (grad.TopGradientReference != ROOTGRADIENT || grad.IndexElements.Count > 1) { grad.IndexElements.RemoveAt(j); } } else { // update key if key in previous sector located at 0 index grad.IndexElements[j].IndexKey = newKey; } if (grad.IndexElements.Count == 0 && grad.TopGradientReference != ROOTGRADIENT) { FreeSectors.Enqueue(grad.Location); AllSectors[grad.Location] = null; removeElement = true; refSector = grad; grad = GetSector(grad.TopGradientReference); nextElement = true; } else if (j == 0 && grad.TopGradientReference != ROOTGRADIENT) { removeElement = false; newKey = grad.IndexElements[j].IndexKey; refSector = grad; grad = GetSector(grad.TopGradientReference); nextElement = true; } break;// } } if (!elementFound) { throw new Exception("reference key to sector not found"); } else if (!nextElement) { break; } } keysCount--; return(true); } else if (idx == 0) { // update ranges TaskQueue.ValueMap <string, object> newKey = currentSector.IndexElements[0].IndexKey; IndexSector refSector = currentSector; IndexSector grad = GetSector(currentSector.TopGradientReference); bool elementFound = true, nextElement = false; while (true) { elementFound = nextElement = false; for (int j = 0; j < grad.IndexElements.Count; j++) { if (grad.IndexElements[j].Reference == refSector.Location) { elementFound = true; grad.IndexElements[j].IndexKey = newKey; if (j == 0 && grad.TopGradientReference != ROOTGRADIENT) { refSector = grad; grad = GetSector(grad.TopGradientReference); nextElement = true; } break; // } } if (!elementFound) { throw new Exception("reference key to sector not found"); } else if (!nextElement) { break; } } // removed successfully keysCount--; return(true); } } else { // not found return(false); } } else { IndexElement el = null; if (outCmp == 0) { el = currentSector.IndexElements[idx]; } else { el = currentSector.IndexElements[idx > 0 ? idx - 1 : idx]; } currentSector = GetSector(el.Reference); // go deeper } } // not found return(false); }
public void Add(TaskQueue.ValueMap <string, object> key) { int outCmp = 0, idx; if (RootGradient.IndexElements.Count == 0) { initialSector.IndexElements.Add(new IndexElement(key)); RootGradient.IndexElements.Add(new IndexElement(key) { Reference = initialSector.Location }); keysCount++; return; } IndexSector currentSector = RootGradient; for (int i = 0; i < MAXGRADIENTLEVEL; i++) { idx = currentSector.BinarySearch(key, out outCmp); if (currentSector.IsSerial) { if (outCmp == 0 && currentSector.IndexElements.Count > 0) { // duplicates not allowed throw new Exception("duplicates not allowed"); // actually allowed, but in this way remove operation will not perform correctly } Queue <QOperation> operationsQueue = new Queue <QOperation>(); operationsQueue.Enqueue(new QOperation() { Key = key, OpType = QOperationType.ADDKEY, Reference = currentSector, index = idx }); while (operationsQueue.Count > 0) { QOperation op = operationsQueue.Dequeue(); switch (op.OpType) { case QOperationType.ADDKEY: if (op.index < 0) { op.index = op.Reference.BinarySearch(op.Key, out outCmp); } IndexElement new_element; if (op.Reference.IsSerial) { new_element = new IndexElement(op.Key); } else { new_element = new IndexElement(op.Key) { Reference = op.location } }; if (op.Reference.IndexElements.Count == (op.Reference.IsSerial ? IndexMaxElementsCount : GradMaxElementsCount)) { if (!op.Reference.IsSerial && op.Reference.TopGradientReference == ROOTGRADIENT) { // allocate new root gradient IndexSector new_root_sector = new IndexSector(comparator, false); new_root_sector.IndexElements = new List <IndexElement>(); new_root_sector.IndexElements.Add(new IndexElement(op.Reference.IndexElements[0].IndexKey) { Reference = op.Reference.Location }); new_root_sector.TopGradientReference = ROOTGRADIENT; SetSector(new_root_sector); op.Reference.TopGradientReference = new_root_sector.Location; RootGradient = new_root_sector; } IndexSector grad = GetSector(op.Reference.TopGradientReference); // overflow IndexSector new_sector = new IndexSector(comparator, op.Reference.IsSerial); new_sector.IndexElements = new List <IndexElement>(); new_sector.TopGradientReference = op.Reference.TopGradientReference; // split.... if (op.index != op.Reference.IndexElements.Count) { //for (int j = op.index; j < op.Reference.IndexElements.Count; j++) //{ // if (comparator.Compare(op.Key, op.Reference.IndexElements[j].IndexKey) == 0) op.index++; //} op.Reference.IndexElements.Insert(op.index, new_element); int cutindex = op.Reference.IndexElements.Count / 2; new_sector.IndexElements = op.Reference.IndexElements.GetRange(cutindex, op.Reference.IndexElements.Count - cutindex); op.Reference.IndexElements.RemoveRange(cutindex, op.Reference.IndexElements.Count - cutindex); SetSector(new_sector); if (op.index == 0) { operationsQueue.Enqueue(new QOperation() { OpType = QOperationType.UPDATEGRADIENTKEY, Key = key, Reference = grad, location = op.Reference.Location }); } if (!op.Reference.IsSerial) { for (int j = 0; j < new_sector.IndexElements.Count; j++) { IndexSector reftoup = GetSector(new_sector.IndexElements[j].Reference); reftoup.TopGradientReference = new_sector.Location; } } } else { // split not required new_sector.IndexElements.Add(new_element); SetSector(new_sector); if (!new_sector.IsSerial) { IndexSector reftoup = GetSector(new_element.Reference); reftoup.TopGradientReference = new_sector.Location; } } operationsQueue.Enqueue(new QOperation() { OpType = QOperationType.ADDKEY, Key = new_sector.IndexElements[0].IndexKey, Reference = grad, index = -1, location = new_sector.Location }); } else { // just add element //if (op.index == 0) // for (int j = op.index; j < op.Reference.IndexElements.Count; j++) // { // if (comparator.Compare(op.Key, op.Reference.IndexElements[j].IndexKey) == 0) op.index++; // } op.Reference.IndexElements.Insert(op.index, new_element); if ((op.index == 0 || op.Reference.IndexElements.Count == 1) && op.Reference.TopGradientReference != ROOTGRADIENT) { operationsQueue.Enqueue(new QOperation() { OpType = QOperationType.UPDATEGRADIENTKEY, Key = new_element.IndexKey, Reference = GetSector(op.Reference.TopGradientReference), location = op.Reference.Location }); } } break; case QOperationType.UPDATEGRADIENTKEY: for (int j = 0; j < op.Reference.IndexElements.Count; j++) { if (op.Reference.IndexElements[j].Reference == op.location) { op.Reference.IndexElements[j].IndexKey = op.Key; if (j == 0 && op.Reference.TopGradientReference != ROOTGRADIENT) { operationsQueue.Enqueue(new QOperation() { OpType = QOperationType.UPDATEGRADIENTKEY, Key = op.Key, Reference = GetSector(op.Reference.TopGradientReference), location = op.Reference.Location }); } break; } } break; default: break; } } //-------------- break; } else { IndexElement el = null; if (outCmp == 0) { el = currentSector.IndexElements[idx]; } else { el = currentSector.IndexElements[idx > 0 ? idx - 1 : idx]; } currentSector = GetSector(el.Reference); // go deeper } } keysCount++; }