public bool Seek(Slice key)
 {
     if (this.ValidateCurrentKey(Current, _cmp) == false)
     {
         return(false);
     }
     CurrentKey = NodeHeader.GetData(_tx, _item);
     return(true);
 }
Exemple #2
0
        public void MultiAdd(Transaction tx, Slice key, Slice value, ushort?version = null)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (value.Size > tx.DataPager.MaxNodeSize)
            {
                throw new ArgumentException(
                          "Cannot add a value to child tree that is over " + tx.DataPager.MaxNodeSize + " bytes in size", "value");
            }
            if (value.Size == 0)
            {
                throw new ArgumentException("Cannot add empty value to child tree");
            }

            State.IsModified = true;
            Lazy <Cursor> lazy;
            var           page = FindPageFor(tx, key, out lazy);

            if (page == null || page.LastMatch != 0)
            {
                var ptr = DirectAdd(tx, key, value.Size, version: version);
                value.CopyTo(ptr);
                return;
            }

            page = tx.ModifyPage(page.PageNumber, page);

            var item = page.GetNode(page.LastSearchPosition);

            CheckConcurrency(key, version, item->Version, TreeActionType.Add);
            var existingValue = new Slice(DirectRead(tx, key), (ushort)item->DataSize);

            if (existingValue.Compare(value, _cmp) == 0)
            {
                return;                 //nothing to do, the exact value is already there
            }
            if (item->Flags == NodeFlags.MultiValuePageRef)
            {
                var tree = OpenOrCreateMultiValueTree(tx, key, item);
                tree.DirectAdd(tx, value, 0);
            }
            else             // need to turn to tree
            {
                var tree    = Create(tx, _cmp, TreeFlags.MultiValue);
                var current = NodeHeader.GetData(tx, item);
                tree.DirectAdd(tx, current, 0);
                tree.DirectAdd(tx, value, 0);
                tx.AddMultiValueTree(this, key, tree);

                // we need to record that we switched to tree mode here, so the next call wouldn't also try to create the tree again
                DirectAdd(tx, key, sizeof(TreeRootHeader), NodeFlags.MultiValuePageRef);
            }
        }
Exemple #3
0
        public void MultiAdd(Transaction tx, Slice key, Slice value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            if (value.Size > tx.Pager.MaxNodeSize)
            {
                throw new ArgumentException("Cannot add a value to child tree that is over " + tx.Pager.MaxNodeSize + " bytes in size", "value");
            }
            if (value.Size == 0)
            {
                throw new ArgumentException("Cannot add empty value to child tree");
            }

            using (var cursor = tx.NewCursor(this))
            {
                var page = FindPageFor(tx, key, cursor);

                if (page == null || page.LastMatch != 0)
                {
                    var ptr = DirectAdd(tx, key, value.Size);
                    value.CopyTo(ptr);
                    return;
                }

                var txInfo = tx.GetTreeInformation(this);

                page = tx.ModifyCursor(txInfo, cursor);

                var item = page.GetNode(page.LastSearchPosition);

                if (item->Flags == NodeFlags.MultiValuePageRef)
                {
                    var tree = OpenOrCreateMultiValueTree(tx, key, item);
                    tree.DirectAdd(tx, value, 0);
                }
                else // need to turn to tree
                {
                    var tree    = Create(tx, _cmp, TreeFlags.MultiValue);
                    var current = NodeHeader.GetData(tx, item);
                    tree.DirectAdd(tx, current, 0);
                    tree.DirectAdd(tx, value, 0);
                    tx.AddMultiValueTree(this, key, tree);

                    DirectAdd(tx, key, sizeof(TreeRootHeader));

                    cursor.Clear();
                    page = FindPageFor(tx, key, cursor);
                    Debug.Assert(page.LastMatch == 0);
                    page.GetNode(page.LastSearchPosition)->Flags = NodeFlags.MultiValuePageRef;
                }
            }
        }