public RelationAdvancedOrderedEnumerator(IRelationDbManipulator manipulator,
                                                 ByteBuffer prefixBytes, uint prefixFieldCount,
                                                 EnumerationOrder order,
                                                 KeyProposition startKeyProposition, ByteBuffer startKeyBytes,
                                                 KeyProposition endKeyProposition, ByteBuffer endKeyBytes, bool initKeyReader, int loaderIndex)
        {
            _prefixFieldCount = prefixFieldCount;
            _manipulator      = manipulator;
            ItemLoader        = _manipulator.RelationInfo.ItemLoaderInfos[loaderIndex];
            _tr        = manipulator.Transaction;
            _ascending = order == EnumerationOrder.Ascending;

            _keyValueTr            = _tr.KeyValueDBTransaction;
            _keyValueTrProtector   = _tr.TransactionProtector;
            _prevProtectionCounter = _keyValueTrProtector.ProtectionCounter;

            _keyBytes = prefixBytes;
            if (endKeyProposition == KeyProposition.Included)
            {
                endKeyBytes = RelationAdvancedEnumerator <TValue> .FindLastKeyWithPrefix(_keyBytes, endKeyBytes,
                                                                                         _keyValueTr, _keyValueTrProtector);
            }

            _keyValueTrProtector.Start();
            _keyValueTr.SetKeyPrefix(_keyBytes);

            long startIndex;
            long endIndex;

            if (endKeyProposition == KeyProposition.Ignored)
            {
                endIndex = _keyValueTr.GetKeyValueCount() - 1;
            }
            else
            {
                switch (_keyValueTr.Find(endKeyBytes))
                {
                case FindResult.Exact:
                    endIndex = _keyValueTr.GetKeyIndex();
                    if (endKeyProposition == KeyProposition.Excluded)
                    {
                        endIndex--;
                    }

                    break;

                case FindResult.Previous:
                    endIndex = _keyValueTr.GetKeyIndex();
                    break;

                case FindResult.Next:
                    endIndex = _keyValueTr.GetKeyIndex() - 1;
                    break;

                case FindResult.NotFound:
                    endIndex = -1;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            if (startKeyProposition == KeyProposition.Ignored)
            {
                startIndex = 0;
            }
            else
            {
                switch (_keyValueTr.Find(startKeyBytes))
                {
                case FindResult.Exact:
                    startIndex = _keyValueTr.GetKeyIndex();
                    if (startKeyProposition == KeyProposition.Excluded)
                    {
                        startIndex++;
                    }

                    break;

                case FindResult.Previous:
                    startIndex = _keyValueTr.GetKeyIndex() + 1;
                    break;

                case FindResult.Next:
                    startIndex = _keyValueTr.GetKeyIndex();
                    break;

                case FindResult.NotFound:
                    startIndex = 0;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            _count     = (uint)Math.Max(0, endIndex - startIndex + 1);
            _startPos  = (uint)(_ascending ? startIndex : endIndex);
            _pos       = 0;
            _seekState = SeekState.Undefined;

            if (initKeyReader)
            {
                var primaryKeyFields       = manipulator.RelationInfo.ClientRelationVersionInfo.GetPrimaryKeyFields();
                var advancedEnumParamField = primaryKeyFields[(int)_prefixFieldCount];
                if (advancedEnumParamField.Handler.NeedsCtx())
                {
                    throw new BTDBException("Not supported.");
                }
                _keyReader = (Func <AbstractBufferedReader, IReaderCtx, TKey>)manipulator.RelationInfo
                             .GetSimpleLoader(new RelationInfo.SimpleLoaderType(advancedEnumParamField.Handler, typeof(TKey)));

                _lengthOfNonDataPrefix = manipulator.RelationInfo.Prefix.Length;
            }
        }
Exemple #2
0
        public long CountWithProposition(ByteBuffer prefixBytes,
                                         KeyProposition startKeyProposition, ByteBuffer startKeyBytes,
                                         KeyProposition endKeyProposition, ByteBuffer endKeyBytes)
        {
            var keyValueTrProtector = _transaction.TransactionProtector;

            if (endKeyProposition == KeyProposition.Included)
            {
                endKeyBytes = RelationAdvancedEnumerator <T> .FindLastKeyWithPrefix(prefixBytes, endKeyBytes, _kvtr, keyValueTrProtector);
            }

            keyValueTrProtector.Start();
            _kvtr.SetKeyPrefix(prefixBytes);

            long startIndex;
            long endIndex;

            if (endKeyProposition == KeyProposition.Ignored)
            {
                endIndex = _kvtr.GetKeyValueCount() - 1;
            }
            else
            {
                switch (_kvtr.Find(endKeyBytes))
                {
                case FindResult.Exact:
                    endIndex = _kvtr.GetKeyIndex();
                    if (endKeyProposition == KeyProposition.Excluded)
                    {
                        endIndex--;
                    }
                    break;

                case FindResult.Previous:
                    endIndex = _kvtr.GetKeyIndex();
                    break;

                case FindResult.Next:
                    endIndex = _kvtr.GetKeyIndex() - 1;
                    break;

                case FindResult.NotFound:
                    endIndex = -1;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            if (startKeyProposition == KeyProposition.Ignored)
            {
                startIndex = 0;
            }
            else
            {
                switch (_kvtr.Find(startKeyBytes))
                {
                case FindResult.Exact:
                    startIndex = _kvtr.GetKeyIndex();
                    if (startKeyProposition == KeyProposition.Excluded)
                    {
                        startIndex++;
                    }
                    break;

                case FindResult.Previous:
                    startIndex = _kvtr.GetKeyIndex() + 1;
                    break;

                case FindResult.Next:
                    startIndex = _kvtr.GetKeyIndex();
                    break;

                case FindResult.NotFound:
                    startIndex = 0;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            return(Math.Max(0, endIndex - startIndex + 1));
        }