Esempio n. 1
0
        private bool SequentialApply(IOperationCollection operations, IOrderedSet <IData, IData> data)
        {
            switch (operations.CommonAction)
            {
            case OperationCode.REPLACE:
            case OperationCode.INSERT_OR_IGNORE:
            {
                foreach (var operation in operations)
                {
                    ValueOperation opr = (ValueOperation)operation;
                    data.UnsafeAdd(opr.FromKey, opr.Record);
                }

                return(true);
            }

            case OperationCode.DELETE:
            {
                return(false);
            }

            case OperationCode.DELETE_RANGE:
            case OperationCode.CLEAR:
            {
                throw new Exception("Logical error.");
            }

            default:
                throw new NotSupportedException();
            }
        }
Esempio n. 2
0
        private bool SequentialApply(IOperationCollection operations, IOrderedSet<IData, IData> data)
        {
            switch (operations.CommonAction)
            {
                case OperationCode.REPLACE:
                case OperationCode.INSERT_OR_IGNORE:
                    {
                        foreach (var operation in operations)
                        {
                            ValueOperation opr = (ValueOperation)operation;
                            data.UnsafeAdd(opr.FromKey, opr.Record);
                        }

                        return true;
                    }
                case OperationCode.DELETE:
                    {
                        return false;
                    }

                case OperationCode.DELETE_RANGE:
                case OperationCode.CLEAR:
                    {
                        throw new Exception("Logical error.");
                    }
                default:
                    throw new NotSupportedException();
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Returns the smallest value.
        /// </summary>
        /// <param name="Matrix">Matrix of values. Must not be empty.</param>
        /// <param name="Node">Node performing the evaluation.</param>
        /// <returns>Smallest value.</returns>
        public static IElement CalcMin(IMatrix Matrix, ScriptNode Node)
        {
            IElement    Result = null;
            IOrderedSet S      = null;

            foreach (IElement E in Matrix.ChildElements)
            {
                if (E.AssociatedObjectValue is null)
                {
                    continue;
                }

                if (Result is null || S.Compare(Result, E) > 0)
                {
                    Result = E;
                    S      = Result.AssociatedSet as IOrderedSet;
                    if (S is null)
                    {
                        throw new ScriptRuntimeException("Cannot compare operands.", Node);
                    }
                }
            }

            if (Result is null)
            {
                return(ObjectValue.Null);
            }
            else
            {
                return(Result);
            }
        }
Esempio n. 4
0
            public override void Load(Stream stream)
            {
                BinaryReader reader = new BinaryReader(stream);

                if (reader.ReadByte() != VERSION)
                {
                    throw new Exception("Invalid LeafNode version.");
                }

                long id = (long)CountCompression.Deserialize(reader);

                if (id != Branch.NodeHandle)
                {
                    throw new Exception("Wtree logical error.");
                }

                int count = (int)CountCompression.Deserialize(reader);

                for (int i = 0; i < count; i++)
                {
                    Locator path = Branch.Tree.DeserializeLocator(reader);
                    IOrderedSet <IData, IData> data = path.OrderedSetPersist.Read(reader);
                    Container[path] = data;

                    RecordCount += data.Count;
                }

                IsModified = false;
            }
Esempio n. 5
0
        public bool Leaf(IOperationCollection operations, IOrderedSet<IData, IData> data)
        {
            //sequential optimization
            if (operations.AreAllMonotoneAndPoint && data.IsInternallyOrdered && (data.Count == 0 || operations.Locator.KeyComparer.Compare(data.Last.Key, operations[0].FromKey) < 0))
                return SequentialApply(operations, data);

            //common action optimization
            if (operations.CommonAction != OperationCode.UNDEFINED)
                return CommonApply(operations, data);

            //standart apply
            bool isModified = false;

            foreach (var opr in operations)
            {
                switch (opr.Code)
                {
                    case OperationCode.REPLACE:
                        {
                            data[opr.FromKey] = ((ReplaceOperation)opr).Record;

                            isModified = true;
                        }
                        break;
                    case OperationCode.INSERT_OR_IGNORE:
                        {
                            if (data.ContainsKey(opr.FromKey))
                                continue;

                            data[opr.FromKey] = ((InsertOrIgnoreOperation)opr).Record;

                            isModified = true;
                        }
                        break;
                    case OperationCode.DELETE:
                        {
                            if (data.Remove(opr.FromKey))
                                isModified = true;
                        }
                        break;
                    case OperationCode.DELETE_RANGE:
                        {
                            if (data.Remove(opr.FromKey, true, opr.ToKey, true))
                                isModified = true;
                        }
                        break;
                    case OperationCode.CLEAR:
                        {
                            data.Clear();
                            isModified = true;
                        }
                        break;
                    default:
                        throw new NotImplementedException();
                }
            }

            return isModified;
        }
Esempio n. 6
0
        public IEnumerable <KeyValuePair <IData, IData> > Forward(IData from, bool hasFrom, IData to, bool hasTo)
        {
            if (hasFrom && hasTo && Locator.KeyComparer.Compare(from, to) > 0)
            {
                throw new ArgumentException("from > to");
            }

            Flush();

            StorageEngine.FullKey nearFullKey;
            bool hasNearFullKey;

            WTree.FullKey lastVisitedFullKey = default(WTree.FullKey);
            IOrderedSet <IData, IData> records;

            records = (IOrderedSet <IData, IData>)StorageEngine.FindData(Locator, Locator, hasFrom ? from : null, Direction.Forward, out nearFullKey, out hasNearFullKey, ref lastVisitedFullKey);

            if (records == null)
            {
                if (!hasNearFullKey || !nearFullKey.Locator.Equals(Locator))
                {
                    yield break;
                }

                records = (IOrderedSet <IData, IData>)StorageEngine.FindData(Locator, nearFullKey.Locator, nearFullKey.Key, Direction.Forward, out nearFullKey, out hasNearFullKey, ref lastVisitedFullKey);
            }

            while (records != null)
            {
                Task task = null;
                IOrderedSet <IData, IData> recs = null;

                if (hasNearFullKey && nearFullKey.Locator.Equals(Locator))
                {
                    if (hasTo && records.Count > 0 && Locator.KeyComparer.Compare(records.First.Key, to) > 0)
                    {
                        break;
                    }

                    task = Task.Factory.StartNew(() =>
                    {
                        recs = (IOrderedSet <IData, IData>)StorageEngine.FindData(Locator, nearFullKey.Locator, nearFullKey.Key, Direction.Forward, out nearFullKey, out hasNearFullKey, ref lastVisitedFullKey);
                    });
                }

                foreach (var record in records.Forward(from, hasFrom, to, hasTo))
                {
                    yield return(record);
                }

                if (task != null)
                {
                    task.Wait();
                }

                records = recs;
            }
        }
Esempio n. 7
0
        private bool Replace(IOrderedSet <IData, IData> set, ReplaceOperation operation)
        {
            Debug.Assert(operation.Scope == OperationScope.Point);

            long        from      = ((Data <long>)operation.FromKey).Value;
            int         localFrom = (int)(from % BLOCK_SIZE);
            long        baseFrom  = from - localFrom;
            Data <long> baseKey   = new Data <long>(baseFrom);

            byte[] src = ((Data <byte[]>)operation.Record).Value;
            Debug.Assert(src.Length <= BLOCK_SIZE);
            Debug.Assert(baseFrom == BLOCK_SIZE * ((from + src.Length - 1) / BLOCK_SIZE));

            IData tmp;

            if (set.TryGetValue(baseKey, out tmp))
            {
                Data <byte[]> rec = (Data <byte[]>)tmp;

                if (localFrom == 0 && src.Length >= rec.Value.Length)
                {
                    rec.Value = src;
                }
                else
                {
                    Debug.Assert(src.Length < BLOCK_SIZE);
                    byte[] dst = rec.Value;
                    if (dst.Length > localFrom + src.Length)
                    {
                        src.CopyTo(dst, localFrom);
                    }
                    else
                    {
                        byte[] buffer = new byte[localFrom + src.Length];
                        dst.CopyTo(buffer, 0);
                        src.CopyTo(buffer, localFrom);
                        rec.Value = buffer;
                    }
                }
            }
            else // if element with baseKey is not found
            {
                if (localFrom == 0)
                {
                    set[baseKey] = new Data <byte[]>(src);
                }
                else
                {
                    byte[] values = new byte[localFrom + src.Length];
                    src.CopyTo(values, localFrom);
                    set[baseKey] = new Data <byte[]>(values);
                }
            }

            return(true);
        }
Esempio n. 8
0
        private int Compare(IElement e1, IElement e2)
        {
            IOrderedSet S2 = e2.AssociatedSet as IOrderedSet;

            if (!(e1.AssociatedSet is IOrderedSet S1) || S2 is null || S1 != S2)
            {
                throw new ScriptRuntimeException("Cannot order elements.", this);
            }

            return(S1.Compare(e1, e2));
        }
Esempio n. 9
0
        private bool Delete(IOrderedSet <IData, IData> set, DeleteRangeOperation operation)
        {
            long from = ((Data <long>)operation.FromKey).Slot0;
            long to   = ((Data <long>)operation.ToKey).Slot0;

            int  localFrom = (int)(from % BLOCK_SIZE);
            int  localTo   = (int)(to % BLOCK_SIZE);
            long baseFrom  = from - localFrom;
            long baseTo    = to - localTo;

            long internalFrom = localFrom > 0 ? baseFrom + BLOCK_SIZE : baseFrom;
            long internalTo   = localTo < BLOCK_SIZE - 1 ? baseTo - 1 : baseTo;

            bool isModified = false;

            if (internalFrom <= internalTo)
            {
                isModified = set.Remove(new Data <long>(internalFrom), true, new Data <long>(internalTo), true);
            }

            IData         tmp;
            Data <byte[]> record;

            if (localFrom > 0 && set.TryGetValue(new Data <long>(baseFrom), out tmp))
            {
                record = (Data <byte[]>)tmp;
                if (localFrom < record.Slot0.Length)
                {
                    Array.Clear(record.Slot0, localFrom, baseFrom < baseTo ? record.Slot0.Length - localFrom : localTo - localFrom + 1);
                    isModified = true;
                }
                if (baseFrom == baseTo)
                {
                    return(isModified);
                }
            }

            if (localTo < BLOCK_SIZE - 1 && set.TryGetValue(new Data <long>(baseTo), out tmp))
            {
                record = (Data <byte[]>)tmp;
                if (localTo < record.Slot0.Length - 1)
                {
                    Array.Clear(record.Slot0, 0, localTo + 1);
                    isModified = true;
                }
                else
                {
                    isModified = set.Remove(new Data <long>(baseTo));
                }
            }

            return(isModified);
        }
Esempio n. 10
0
        public void Write(BinaryWriter writer, IOrderedSet <IData, IData> item)
        {
            writer.Write(VERSION);

            if (verticalCompression)
            {
                WriteVertical(writer, item);
            }
            else
            {
                WriteRaw(writer, item);
            }
        }
Esempio n. 11
0
        private void WriteRaw(BinaryWriter writer, IOrderedSet <IData, IData> data)
        {
            lock (data)
            {
                writer.Write(data.Count);
                writer.Write(data.IsInternallyOrdered);

                foreach (var kv in data.InternalEnumerate())
                {
                    keyPersist.Write(writer, kv.Key);
                    recordPersist.Write(writer, kv.Value);
                }
            }
        }
Esempio n. 12
0
        private void WriteVertical(BinaryWriter writer, IOrderedSet <IData, IData> data)
        {
            KeyValuePair <IData, IData>[] rows;

            bool isInternallyOrdered;

            lock (data)
            {
                isInternallyOrdered = data.IsInternallyOrdered;

                rows = new KeyValuePair <IData, IData> [data.Count];
                int index = 0;
                foreach (var kv in data.InternalEnumerate())
                {
                    rows[index++] = kv;
                }

                CountCompression.Serialize(writer, checked ((ulong)rows.Length));
                writer.Write(data.IsInternallyOrdered);
            }

            Action[]       actions = new Action[2];
            MemoryStream[] streams = new MemoryStream[2];

            actions[0] = () =>
            {
                streams[0] = new MemoryStream();
                keyIndexerPersist.Store(new BinaryWriter(streams[0]), (idx) => { return(rows[idx].Key); }, rows.Length);
            };

            actions[1] = () =>
            {
                streams[1] = new MemoryStream();
                recordIndexerPersist.Store(new BinaryWriter(streams[1]), (idx) => { return(rows[idx].Value); }, rows.Length);
            };

            Parallel.Invoke(actions);

            foreach (var stream in streams)
            {
                using (stream)
                {
                    CountCompression.Serialize(writer, checked ((ulong)stream.Length));
                    writer.Write(stream.GetBuffer(), 0, (int)stream.Length);
                }
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Evaluates the node, using the variables provided in the <paramref name="Variables"/> collection.
        /// </summary>
        /// <param name="Variables">Variables collection.</param>
        /// <returns>Result.</returns>
        public override IElement Evaluate(Variables Variables)
        {
            ICommutativeRingWithIdentityElement From = this.left.Evaluate(Variables) as ICommutativeRingWithIdentityElement;

            if (From is null)
            {
                throw new ScriptRuntimeException("Invalid range.", this);
            }

            ICommutativeRingWithIdentityElement To = this.middle.Evaluate(Variables) as ICommutativeRingWithIdentityElement;

            if (To is null)
            {
                throw new ScriptRuntimeException("Invalid range.", this);
            }

            IOrderedSet S = From.AssociatedSet as IOrderedSet;

            if (S is null)
            {
                throw new ScriptRuntimeException("Cannot compare range.", this);
            }

            IElement Step, Last;
            int      Direction = S.Compare(From, To);
            bool     Done;

            if (!(this.middle2 is null))
            {
                Step = this.middle2.Evaluate(Variables);

                if (Direction < 0)
                {
                    if (S.Compare(Step, From.Zero) <= 0)
                    {
                        throw new ScriptRuntimeException("Invalid step size for corresponding range.", this);
                    }
                }
                else if (Direction > 0)
                {
                    if (S.Compare(Step, From.Zero) >= 0)
                    {
                        throw new ScriptRuntimeException("Invalid step size for corresponding range.", this);
                    }
                }
            }
Esempio n. 14
0
        /// <summary>
        /// Evaluates the operator on scalar operands.
        /// </summary>
        /// <param name="Left">Left value.</param>
        /// <param name="Right">Right value.</param>
        /// <param name="Variables">Variables collection.</param>
        /// <returns>Result</returns>
        public override IElement EvaluateScalar(IElement Left, IElement Right, Variables Variables)
        {
            IOrderedSet S = Left.AssociatedSet as IOrderedSet;

            if (S == null)
            {
                throw new ScriptRuntimeException("Cannot compare operands.", this);
            }

            if (S.Compare(Left, Right) > 0)
            {
                return(BooleanValue.True);
            }
            else
            {
                return(BooleanValue.False);
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Evaluates the function on a scalar argument.
        /// </summary>
        /// <param name="Argument1">Function argument 1.</param>
        /// <param name="Argument2">Function argument 2.</param>
        /// <param name="Variables">Variables collection.</param>
        /// <returns>Function result.</returns>
        public override IElement EvaluateScalar(IElement Argument1, IElement Argument2, Variables Variables)
        {
            IOrderedSet S = Argument1.AssociatedSet as IOrderedSet;

            if (S == null)
            {
                throw new ScriptRuntimeException("Unable to compare elements.", this);
            }

            if (S.Compare(Argument1, Argument2) > 0)
            {
                return(Argument1);
            }
            else
            {
                return(Argument2);
            }
        }
Esempio n. 16
0
        public bool Leaf(IOperationCollection operations, IDataContainer data)
        {
            IOrderedSet <IData, IData> set = (IOrderedSet <IData, IData>)data;
            bool isModified = false;

            foreach (var opr in operations)
            {
                switch (opr.Code)
                {
                case OperationCode.REPLACE:
                {
                    if (Replace(set, (ReplaceOperation)opr))
                    {
                        isModified = true;
                    }
                }
                break;

                case OperationCode.DELETE:
                {
                    DeleteRangeOperation o = new DeleteRangeOperation(opr.FromKey, opr.FromKey);
                    if (Delete(set, (DeleteRangeOperation)o))
                    {
                        isModified = true;
                    }
                }
                break;

                case OperationCode.DELETE_RANGE:
                {
                    if (Delete(set, (DeleteRangeOperation)opr))
                    {
                        isModified = true;
                    }
                }
                break;

                default:
                    throw new NotSupportedException();
                }
            }
            return(isModified);
        }
Esempio n. 17
0
        // ReSharper disable once UnusedMember.Global
        public static void DoSave(IWriterCtx ctx, IOrderedSet <TKey>?dictionary, int cfgId)
        {
            var writerCtx = (IDBWriterCtx)ctx;

            if (!(dictionary is ODBSet <TKey> goodDict))
            {
                var tr = writerCtx.GetTransaction();
                var id = tr.AllocateDictionaryId();
                goodDict = new ODBSet <TKey>(tr, (ODBDictionaryConfiguration)writerCtx.FindInstance(cfgId), id);
                if (dictionary != null)
                {
                    foreach (var pair in dictionary)
                    {
                        goodDict.Add(pair);
                    }
                }
            }
            ctx.Writer().WriteVUInt64(goodDict._id);
        }
Esempio n. 18
0
        /// <summary>
        /// All keys in the input set must be less than all keys in the current set OR all keys in the input set must be greater than all keys in the current set.
        /// </summary>
        public void Merge(IOrderedSet <TKey, TValue> set)
        {
            if (set.Count == 0)
            {
                return;
            }

            if (this.Count == 0)
            {
                foreach (var x in set) //set.Forward()
                {
                    list.Add(x);
                }

                return;
            }

            //Debug.Assert(comparer.Compare(this.Last.Key, set.First.Key) < 0 || comparer.Compare(this.First.Key, set.Last.Key) > 0);

            if (list != null)
            {
                int idx = kvComparer.Compare(set.Last, list[0]) < 0 ? 0 : list.Count;
                list.InsertRange(idx, set);
            }
            else if (dictionary != null)
            {
                foreach (var kv in set.InternalEnumerate())
                {
                    this.dictionary.Add(kv.Key, kv.Value); //there should be no exceptions
                }
            }
            else //if (set != null)
            {
                foreach (var kv in set.InternalEnumerate())
                {
                    this.set.Add(kv);
                }
            }
        }
Esempio n. 19
0
        /// <summary>
        /// The hook.
        /// </summary>
        public IOrderedSet <IData, IData> FindData(Locator originalLocator, Locator locator, IData key, Direction direction, out FullKey nearFullKey, out bool hasNearFullKey, ref FullKey lastVisitedFullKey)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("WTree");
            }

            nearFullKey    = default(FullKey);
            hasNearFullKey = false;

            var branch = RootBranch;

            Monitor.Enter(branch);

            if (!isRootCacheLoaded)
            {
                LoadRootCache();
            }

            Params param;

            if (key != null)
            {
                param = new Params(WalkMethod.Cascade, WalkAction.None, null, true, locator, key);
            }
            else
            {
                switch (direction)
                {
                case Direction.Forward:
                    param = new Params(WalkMethod.CascadeFirst, WalkAction.None, null, true, locator);
                    break;

                case Direction.Backward:
                    param = new Params(WalkMethod.CascadeLast, WalkAction.None, null, true, locator);
                    break;

                default:
                    throw new NotSupportedException(direction.ToString());
                }
            }

            branch.Fall(Depth + 1, new Token(CacheSemaphore, CancellationToken.None), param);
            branch.WaitFall();

            switch (direction)
            {
            case Direction.Forward:
            {
                while (branch.NodeType == NodeType.Internal)
                {
                    KeyValuePair <FullKey, Branch> newBranch = ((InternalNode)branch.Node).FindBranch(locator, key, direction, ref nearFullKey, ref hasNearFullKey);

                    Monitor.Enter(newBranch.Value);
                    newBranch.Value.WaitFall();
                    Debug.Assert(!newBranch.Value.Cache.Contains(originalLocator));
                    Monitor.Exit(branch);

                    branch = newBranch.Value;
                }
            }
            break;

            case Direction.Backward:
            {
                int depth = Depth;
                KeyValuePair <FullKey, Branch> newBranch = default(KeyValuePair <FullKey, Branch>);
                while (branch.NodeType == NodeType.Internal)
                {
                    InternalNode node = (InternalNode)branch.Node;
                    newBranch = node.Branches[node.Branches.Count - 1];

                    int cmp = newBranch.Key.Locator.CompareTo(lastVisitedFullKey.Locator);
                    if (cmp == 0)
                    {
                        if (lastVisitedFullKey.Key == null)
                        {
                            cmp = -1;
                        }
                        else
                        {
                            cmp = newBranch.Key.Locator.KeyComparer.Compare(newBranch.Key.Key, lastVisitedFullKey.Key);
                        }
                    }
                    //else
                    //{
                    //    Debug.WriteLine("");
                    //}

                    //newBranch.Key.CompareTo(lastVisitedFullKey) >= 0
                    if (cmp >= 0)
                    {
                        newBranch = node.FindBranch(locator, key, direction, ref nearFullKey, ref hasNearFullKey);
                    }
                    else
                    {
                        if (node.Branches.Count >= 2)
                        {
                            hasNearFullKey = true;
                            nearFullKey    = node.Branches[node.Branches.Count - 2].Key;
                        }
                    }

                    Monitor.Enter(newBranch.Value);
                    depth--;
                    newBranch.Value.WaitFall();
                    if (newBranch.Value.Cache.Contains(originalLocator))
                    {
                        newBranch.Value.Fall(depth + 1, new Token(CacheSemaphore, CancellationToken.None), new Params(WalkMethod.Current, WalkAction.None, null, true, originalLocator));
                        newBranch.Value.WaitFall();
                    }
                    Debug.Assert(!newBranch.Value.Cache.Contains(originalLocator));
                    Monitor.Exit(branch);

                    branch = newBranch.Value;
                }

                //if (lastVisitedFullKey.Locator.Equals(newBranch.Key.Locator) &&
                //    (lastVisitedFullKey.Key != null && lastVisitedFullKey.Locator.KeyEqualityComparer.Equals(lastVisitedFullKey.Key, newBranch.Key.Key)))
                //{
                //    Monitor.Exit(branch);
                //    return null;
                //}

                lastVisitedFullKey = newBranch.Key;
            }
            break;

            default:
                throw new NotSupportedException(direction.ToString());
            }

            IOrderedSet <IData, IData> data = ((LeafNode)branch.Node).FindData(originalLocator, direction, ref nearFullKey, ref hasNearFullKey);

            Monitor.Exit(branch);

            return(data);
        }
Esempio n. 20
0
        private bool CommonApply(IOperationCollection operations, IOrderedSet<IData, IData> data)
        {
            int commonAction = operations.CommonAction;

            int changes = 0;

            switch (commonAction)
            {
                case OperationCode.REPLACE:
                    {
                        foreach (var opr in operations)
                        {
                            data[opr.FromKey] = ((ReplaceOperation)opr).Record;
                            changes++;
                        }
                    }
                    break;

                case OperationCode.INSERT_OR_IGNORE:
                    {
                        foreach (var opr in operations)
                        {
                            if (data.ContainsKey(opr.FromKey))
                                continue;

                            data[opr.FromKey] = ((InsertOrIgnoreOperation)opr).Record;
                            changes++;
                        }
                    }
                    break;

                case OperationCode.DELETE:
                    {
                        foreach (var opr in operations)
                        {
                            if (data.Remove(opr.FromKey))
                                changes++;
                        }
                    }
                    break;

                case OperationCode.DELETE_RANGE:
                    {
                        foreach (var opr in operations)
                        {
                            if (data.Remove(opr.FromKey, true, opr.ToKey, true))
                                changes++;
                        }
                    }
                    break;

                case OperationCode.CLEAR:
                    {
                        foreach (var opr in operations)
                        {
                            data.Clear();
                            changes++;
                            break;
                        }
                    }
                    break;

                default:
                    throw new NotImplementedException();
            }

            return changes > 0;
        }
Esempio n. 21
0
            public IOrderedSet <IData, IData> FindData(Locator locator, Direction direction, ref FullKey nearFullKey, ref bool hasNearFullKey)
            {
                IOrderedSet <IData, IData> data = null;

                Container.TryGetValue(locator, out data);
                if (direction == Direction.None)
                {
                    return(data);
                }

                if (Container.Count == 1 && data != null)
                {
                    return(data);
                }

                IOrderedSet <IData, IData> nearData = null;

                if (direction == Direction.Backward)
                {
                    bool    havePrev = false;
                    Locator prev     = default(Locator);

                    foreach (var kv in Container)
                    {
                        if (kv.Key.CompareTo(locator) < 0)
                        {
                            if (!havePrev || kv.Key.CompareTo(prev) > 0)
                            {
                                prev     = kv.Key;
                                nearData = kv.Value;
                                havePrev = true;
                            }
                        }
                    }

                    if (havePrev)
                    {
                        hasNearFullKey = true;
                        nearFullKey    = new FullKey(prev, nearData.Last.Key);
                    }
                }
                else //if (direction == Direction.Forward)
                {
                    bool    haveNext = false;
                    Locator next     = default(Locator);

                    foreach (var kv in Container)
                    {
                        if (kv.Key.CompareTo(locator) > 0)
                        {
                            if (!haveNext || kv.Key.CompareTo(next) < 0)
                            {
                                next     = kv.Key;
                                nearData = kv.Value;
                                haveNext = true;
                            }
                        }
                    }

                    if (haveNext)
                    {
                        hasNearFullKey = true;
                        nearFullKey    = new FullKey(next, nearData.First.Key);
                    }
                }

                return(data);
            }
Esempio n. 22
0
        /// <summary>
        /// Evaluates the node, using the variables provided in the <paramref name="Variables"/> collection.
        /// </summary>
        /// <param name="Variables">Variables collection.</param>
        /// <returns>Result.</returns>
        public override IElement Evaluate(Variables Variables)
        {
            ICommutativeRingWithIdentityElement From = this.left.Evaluate(Variables) as ICommutativeRingWithIdentityElement;

            if (From == null)
            {
                throw new ScriptRuntimeException("Invalid range.", this);
            }

            ICommutativeRingWithIdentityElement To = this.middle.Evaluate(Variables) as ICommutativeRingWithIdentityElement;

            if (To == null)
            {
                throw new ScriptRuntimeException("Invalid range.", this);
            }

            IOrderedSet S = From.AssociatedSet as IOrderedSet;

            if (S == null)
            {
                throw new ScriptRuntimeException("Cannot compare range.", this);
            }

            IElement Step;
            int      Direction = S.Compare(From, To);
            bool     Done;

            if (this.middle2 != null)
            {
                Step = this.middle2.Evaluate(Variables);

                if (Direction < 0)
                {
                    if (S.Compare(Step, From.Zero) <= 0)
                    {
                        throw new ScriptRuntimeException("Invalid step size for corresponding range.", this);
                    }
                }
                else if (Direction > 0)
                {
                    if (S.Compare(Step, From.Zero) >= 0)
                    {
                        throw new ScriptRuntimeException("Invalid step size for corresponding range.", this);
                    }
                }
            }
            else
            {
                if (Direction <= 0)
                {
                    Step = From.One;
                }
                else
                {
                    Step = From.One.Negate();
                }
            }

            LinkedList <IElement> Elements = new LinkedList <IElement>();

            do
            {
                Variables[this.variableName] = From;
                Elements.AddLast(this.right.Evaluate(Variables));

                if (Direction == 0)
                {
                    Done = true;
                }
                else
                {
                    From = Operators.Arithmetics.Add.EvaluateAddition(From, Step, this) as ICommutativeRingWithIdentityElement;
                    if (From == null)
                    {
                        throw new ScriptRuntimeException("Invalid step size.", this);
                    }

                    if (Direction > 0)
                    {
                        Done = S.Compare(From, To) < 0;
                    }
                    else
                    {
                        Done = S.Compare(From, To) > 0;
                    }
                }
            }while (!Done);

            return(this.Encapsulate(Elements));
        }
Esempio n. 23
0
        private bool CommonApply(IOperationCollection operations, IOrderedSet <IData, IData> data)
        {
            int commonAction = operations.CommonAction;

            int changes = 0;

            switch (commonAction)
            {
            case OperationCode.REPLACE:
            {
                foreach (var opr in operations)
                {
                    data[opr.FromKey] = ((ReplaceOperation)opr).Record;
                    changes++;
                }
            }
            break;

            case OperationCode.INSERT_OR_IGNORE:
            {
                foreach (var opr in operations)
                {
                    if (data.ContainsKey(opr.FromKey))
                    {
                        continue;
                    }

                    data[opr.FromKey] = ((InsertOrIgnoreOperation)opr).Record;
                    changes++;
                }
            }
            break;

            case OperationCode.DELETE:
            {
                foreach (var opr in operations)
                {
                    if (data.Remove(opr.FromKey))
                    {
                        changes++;
                    }
                }
            }
            break;

            case OperationCode.DELETE_RANGE:
            {
                foreach (var opr in operations)
                {
                    if (data.Remove(opr.FromKey, true, opr.ToKey, true))
                    {
                        changes++;
                    }
                }
            }
            break;

            case OperationCode.CLEAR:
            {
                foreach (var opr in operations)
                {
                    data.Clear();
                    changes++;
                    break;
                }
            }
            break;

            default:
                throw new NotImplementedException();
            }

            return(changes > 0);
        }
Esempio n. 24
0
        public bool Leaf(IOperationCollection operations, IOrderedSet <IData, IData> data)
        {
            //sequential optimization
            if (operations.AreAllMonotoneAndPoint && data.IsInternallyOrdered && (data.Count == 0 || operations.Locator.KeyComparer.Compare(data.Last.Key, operations[0].FromKey) < 0))
            {
                return(SequentialApply(operations, data));
            }

            //common action optimization
            if (operations.CommonAction != OperationCode.UNDEFINED)
            {
                return(CommonApply(operations, data));
            }

            //standart apply
            bool isModified = false;

            foreach (var opr in operations)
            {
                switch (opr.Code)
                {
                case OperationCode.REPLACE:
                {
                    data[opr.FromKey] = ((ReplaceOperation)opr).Record;

                    isModified = true;
                }
                break;

                case OperationCode.INSERT_OR_IGNORE:
                {
                    if (data.ContainsKey(opr.FromKey))
                    {
                        continue;
                    }

                    data[opr.FromKey] = ((InsertOrIgnoreOperation)opr).Record;

                    isModified = true;
                }
                break;

                case OperationCode.DELETE:
                {
                    if (data.Remove(opr.FromKey))
                    {
                        isModified = true;
                    }
                }
                break;

                case OperationCode.DELETE_RANGE:
                {
                    if (data.Remove(opr.FromKey, true, opr.ToKey, true))
                    {
                        isModified = true;
                    }
                }
                break;

                case OperationCode.CLEAR:
                {
                    data.Clear();
                    isModified = true;
                }
                break;

                default:
                    throw new NotImplementedException();
                }
            }

            return(isModified);
        }
Esempio n. 25
0
        public IEnumerable <KeyValuePair <IData, IData> > Backward(IData to, bool hasTo, IData from, bool hasFrom)
        {
            lock (SyncRoot)
            {
                var keyComparer = Locator.KeyComparer;

                if (hasFrom && hasTo && keyComparer.Compare(from, to) > 0)
                {
                    throw new ArgumentException("from > to");
                }

                Flush();

                WTree.FullKey nearFullKey;
                bool          hasNearFullKey;
                IOrderedSet <IData, IData> records;

                WTree.FullKey lastVisitedFullKey = new WTree.FullKey(Locator, to);
                records = Tree.FindData(Locator, Locator, hasTo ? to : null, Direction.Backward, out nearFullKey, out hasNearFullKey, ref lastVisitedFullKey);

                if (records == null)
                {
                    yield break;
                }

                while (records != null)
                {
                    Task task = null;
                    IOrderedSet <IData, IData> recs = null;

                    //if (records.Count > 0)
                    //    lastVisitedFullKey = new WTree.FullKey(Locator, records.First.Key);

                    if (hasNearFullKey)
                    {
                        lock (records)
                        {
                            if (hasFrom && records.Count > 0 && keyComparer.Compare(records.Last.Key, from) < 0)
                            {
                                break;
                            }
                        }

                        task = Task.Factory.StartNew(() =>
                        {
                            recs = Tree.FindData(Locator, nearFullKey.Locator, nearFullKey.Key, Direction.Backward, out nearFullKey, out hasNearFullKey, ref lastVisitedFullKey);
                        });
                    }

                    lock (records)
                    {
                        foreach (var record in records.Backward(to, hasTo, from, hasFrom))
                        {
                            yield return(record);
                        }
                    }

                    if (task != null)
                    {
                        task.Wait();
                    }

                    if (recs == null)
                    {
                        break;
                    }

                    lock (records)
                    {
                        lock (recs)
                        {
                            if (recs.Count > 0 && records.Count > 0)
                            {
                                if (keyComparer.Compare(recs.First.Key, records.First.Key) >= 0)
                                {
                                    break;
                                }
                            }
                        }
                    }

                    records = recs;
                }
            }
        }