Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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++;
        }