示例#1
0
        private bool InternalAddItem(TItem item, TOpEnum op, InsertionBehavior behavior)
        {
            if (item == null)
            {
                return(false);
            }

            var itemDataType = GetItemOrgDataType(item);

            if (itemDataType != null)
            {
                if (_matchedItemsType != null) //本块内所含各项与项,项与块整集之间的匹配类型
                {
                    var tmpType = TypeMatcher.MatchDataTtype(_matchedItemsType, itemDataType, out _);
                    if (tmpType != null)
                    {
                        _matchedItemsType = tmpType;
                    }
                    else //匹配失败
                    {
                        throw new ArithmeticException(MsgStrings.InvalidTypeConvert(itemDataType, _matchedItemsType));
                    }
                }
                else
                {
                    _matchedItemsType = itemDataType; //首次加入的具有非空值项,
                }
            }
            ReMatchDataType();
            _itemVersion++;
            _hashCodeVersion++;
            return(m_items.Add(op, item, behavior));
        }
示例#2
0
        public int AddItem(string opName, InsertionBehavior behavior, params TItem[] itemArray)
        {
            if (GetOperatorWithString == null)
            {
                throw new Exception(string.Format(MsgStrings.NullGetOperatorWithStringDelegate, nameof(GetOperatorWithString)));
            }

            var op = GetOperatorWithString(opName);

            return(AddItem(op, behavior, itemArray));
        }
示例#3
0
        public int AddBlock(string opName, InsertionBehavior behavior, params TBlock[] blocks)
        {
            if (GetOperatorWithString == null)
            {
                throw new Exception(string.Format(MsgStrings.NullGetOperatorWithStringDelegate, nameof(GetOperatorWithString)));
            }

            var op = GetOperatorWithString.Invoke(opName);

            return(AddBlock(op, behavior, blocks));
        }
示例#4
0
        public int AddItem(TOpEnum op, InsertionBehavior behavior, params TItem[] itemArray)
        {
            var id = 0;

            foreach (TItem p in itemArray)
            {
                if (InternalAddItem(p, op, behavior))
                {
                    id++;
                }
            }
            return(id);
        }
示例#5
0
        public int AddBlock(TOpEnum op, InsertionBehavior behavior, params TBlock[] blocks)
        {
            var id = 0;

            foreach (TBlock p in blocks)
            {
                if (InternalAddBlock(p, op, behavior))
                {
                    id++;
                }
            }
            return(id);
        }
示例#6
0
        private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
        {
            if (key == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
            }

            _version++;
            if (_buckets == null)
            {
                Initialize(0);
            }

            Entry[] entries = _entries;
            IEqualityComparer <TKey> comparer = _comparer;

            int hashCode = ((comparer == null) ? key.GetHashCode() : comparer.GetHashCode(key)) & 0x7FFFFFFF;

            int     collisionCount = 0;
            ref int bucket         = ref _buckets[hashCode % _buckets.Length];
示例#7
0
        private bool InternalAddBlock(TBlock block, TOpEnum op, InsertionBehavior behavior)
        {
            if (block == null)
            {
                return(false);
            }

            //var blockType = typeof(TBlock);
            //var blockAllCount = blockType.GetProperty(nameof(AllCount))?.GetValue(block) ?? 0;

            var blockAllCount = block.AllCount;

            if ((int)blockAllCount == 0)
            {
                return(false);
            }


            //var blockParent = blockType.GetProperty(nameof(ParentBlock));
            //blockParent.SetValue(block, this);
            var subBlockDataType = GetBlockOrgDataType(block);

            if (subBlockDataType != null)
            {
                if (_matchedSubBlocksDataType != null) //本块内所含各子块之间的匹配类型
                {
                    var tmpType = TypeMatcher.MatchDataTtype(_matchedSubBlocksDataType, subBlockDataType, out _);
                    if (tmpType != null)
                    {
                        _matchedSubBlocksDataType = tmpType;
                    }
                    else //匹配失败
                    {
                        throw new ArithmeticException(MsgStrings.InvalidTypeConvert(subBlockDataType, _matchedSubBlocksDataType));
                    }
                }
                else
                {
                    _matchedSubBlocksDataType = subBlockDataType; //加入的是第一个具有块类型的子块,
                }

                //if (_matchedDataType != null) //需要重新匹配本块的类型
                //{
                //    tmpType = TypeMatcher.MatchDataTtype(_matchedDataType, _matchedSubBlocksDataType, out _);
                //    if (tmpType != null)
                //        _matchedDataType = tmpType;
                //    else  //匹配失败
                //        throw new ArithmeticException(MsgStrings.InvalidTypeConvert( subBlockDataType));
                //}
                //else
                //{
                //    _matchedDataType = _matchedSubBlocksDataType;//首次确认本块的整体类型
                //}

                ReMatchDataType();
            }


            _blockVersion++;
            _hashCodeVersion++;
            return(m_blocks.Add(op, block, behavior));
        }
示例#8
0
 public NodeBlock(string opName, InsertionBehavior behavior, params NodeBlock[] block) : base(opName, behavior, block)
 {
 }
示例#9
0
 /// <summary>
 /// 传入一个查询项数组,构造实例
 /// </summary>
 /// <param name="op">逻辑连接符,指示与同一块内其它项或子块之间的逻辑关系</param>
 /// <param name="behavior">指示条件之间是否重复的行为</param>
 /// <param name="itemArray">包含要添加的项的数组</param>
 public QueryBlock(TOpEnum op, InsertionBehavior behavior, params TItem[] itemArray) : this()
 {
     AddItem(op, behavior, itemArray);
 }
示例#10
0
 /// <summary>
 /// 传入一个查询块,构造实例
 /// </summary>
 /// <param name="op">逻辑连接符,与块内其它子块或项之间逻辑关系</param>
 /// <param name="behavior">是否阻止添加具有相同逻辑连接符的重复的块</param>
 /// <param name="blocks">包含要加入的块的数组</param>
 public QueryBlock(TOpEnum op, InsertionBehavior behavior, params TBlock[] blocks) : this()
 {
     AddBlock(op, behavior, blocks);
 }
示例#11
0
 public int Add(TOpEnum op, InsertionBehavior behavior, params TItem[] items)
 {
     return(AddItem(op, behavior, items));
 }
示例#12
0
        private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            if (buckets == null)
            {
                Initialize(0);
            }
            int hashCode       = comparer.GetHashCode(key) & 0x7FFFFFFF;
            int targetBucket   = hashCode % buckets.Length;
            int collisionCount = 0;

            for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next)
            {
                if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
                {
                    if (behavior == InsertionBehavior.OverwriteExisting)
                    {
                        entries[i].value = value;
                        version++;
                        return(true);
                    }

                    if (behavior == InsertionBehavior.ThrowOnExisting)
                    {
                        throw new ArgumentException(SR.Format(SR.Argument_AddingDuplicate, key));
                    }

                    return(false);
                }
                collisionCount++;
            }

            int index;

            if (freeCount > 0)
            {
                index    = freeList;
                freeList = entries[index].next;
                freeCount--;
            }
            else
            {
                if (count == entries.Length)
                {
                    Resize();
                    targetBucket = hashCode % buckets.Length;
                }
                index = count;
                count++;
            }

            entries[index].hashCode = hashCode;
            entries[index].next     = buckets[targetBucket];
            entries[index].key      = key;
            entries[index].value    = value;
            buckets[targetBucket]   = index;
            version++;

            if (collisionCount > HashHelpers.HashCollisionThreshold && comparer is NonRandomizedStringEqualityComparer)
            {
                comparer = (IEqualityComparer <TKey>)EqualityComparer <string> .Default;
                Resize(entries.Length, true);
            }

            return(true);
        }
示例#13
0
        public bool TryInsert(string key, TValue value, InsertionBehavior behavior)
        {
            if (_buckets == null)
            {
                Initialize(0);
            }

            Entry[] entries = _entries;

            int hashCode = _comparer.GetHashCode(key) & 0x7FFFFFFF;

            int collisionCount = 0;
            int bucket         = _buckets[hashCode % _buckets.Length];
            // Value in _buckets is 1-based
            int i = bucket - 1;

            do
            {
                // Should be a while loop https://github.com/dotnet/coreclr/issues/15476
                // Test uint in if rather than loop condition to drop range check for following array access
                if ((uint)i >= (uint)entries.Length)
                {
                    break;
                }

                if (entries[i].hashCode == hashCode && entries[i].key == key)
                {
                    if (behavior == InsertionBehavior.OverwriteExisting)
                    {
                        entries[i].value = value;
                        return(true);
                    }

                    if (behavior == InsertionBehavior.SkipIfExists)
                    {
                        return(true);
                    }

                    if (behavior == InsertionBehavior.ThrowOnExisting)
                    {
                        ExceptionHelper.ThrowArgumentException("key already exists");
                    }

                    return(false);
                }

                i = entries[i].next;
                if (collisionCount >= entries.Length)
                {
                    // The chain of entries forms a loop; which means a concurrent update has happened.
                    // Break out of the loop and throw, rather than looping forever.
                    ExceptionHelper.ThrowInvalidOperationException();
                }

                collisionCount++;
            } while (true);

            bool updateFreeList = false;
            int  index;

            if (_freeCount > 0)
            {
                index          = _freeList;
                updateFreeList = true;
                _freeCount--;
            }
            else
            {
                int count = _count;
                if (count == entries.Length)
                {
                    Resize();
                    bucket = _buckets[hashCode % _buckets.Length];
                }

                index   = count;
                _count  = count + 1;
                entries = _entries;
            }

            Entry entry = entries[index];

            if (updateFreeList)
            {
                _freeList = entry.next;
            }

            entry.hashCode = hashCode;
            // Value in _buckets is 1-based
            entry.next  = bucket - 1;
            entry.key   = key;
            entry.value = value;
            // Value in _buckets is 1-based
            bucket = index + 1;

            return(true);
        }
示例#14
0
 public NodeBlock(string opName, InsertionBehavior behavior, params QueryItem[] items) : base(opName, behavior, items)
 {
 }
示例#15
0
 public NodeBlock(QueryArithmetic op, InsertionBehavior behavior, params QueryItem[] items) : base(op, behavior, items)
 {
 }
示例#16
0
 public int Add(string opName, InsertionBehavior behavior, params TItem[] items)
 {
     return(AddItem(opName, behavior, items));
 }
示例#17
0
 public int Add(TOpEnum op, InsertionBehavior behavior, params TBlock[] blocks)
 {
     return(AddBlock(op, behavior, blocks));
 }
示例#18
0
 /// <summary>
 /// 传入一个查询块数组,构造实例
 /// </summary>
 /// <param name="op">逻辑连接符,指示与块与块之间,项与项之间,项与块之间的逻辑关系</param>
 /// <param name="behavior">指示是否重复的行为</param>
 /// <param name="itemArray">包含要添加的块的数组</param>
 public QueryBlock(string opName, InsertionBehavior behavior, params TBlock[] blocks) : this()
 {
     AddBlock(opName, behavior, blocks);
 }
示例#19
0
 public int Add(string opName, InsertionBehavior behavior, params TBlock[] blocks)
 {
     return(AddBlock(opName, behavior, blocks));
 }
示例#20
0
 public QueryBlock(string opName, InsertionBehavior behavior, params TItem[] itemArray)
 {
     AddItem(opName, behavior, itemArray);
 }
示例#21
0
 public NodeBlock(QueryArithmetic op, InsertionBehavior behavior, params NodeBlock[] block) : base(op, behavior, block)
 {
 }