Пример #1
0
        public async Task AddItemAsync(T new_key, int[] new_value, AddedItem <T> addedItem)
        {
            // Find the key after the spot where this item goes.
            int spot = 0;

            while (spot < NumKeysUsed)
            {
                if (this.Compare(Keys[spot], new_key) >= 0)
                {
                    break;
                }
                spot++;
            }

            // See if we found it.
            if ((spot < NumKeysUsed) && (this.Compare(Keys[spot], new_key) == 0))
            {
                Array.Resize <int>(ref Values[spot], Values[spot].Length + 1);
                Values[spot][Values[spot].Length - 1] = new_value[0];
                addedItem.up_key   = default(T);
                addedItem.up_value = null;
                addedItem.up_node  = null;
                await this.PersistAsync().ConfigureAwait(false);

                return;
            }
            await CheckChildrenAsync().ConfigureAwait(false);

            // See if we are in a leaf node.
            if (Children[0] == null)
            {
                // This is a leaf.
                await AddItemToNodeAsync(spot, new_key, new_value, null, addedItem).ConfigureAwait(false);
            }
            else
            {
                // This is not a leaf. Move into the proper subtree.
                await Children[spot].AddItemAsync(new_key, new_value, addedItem).ConfigureAwait(false);

                // See if we had a bucket split.
                if (addedItem.up_node != null)
                {
                    // We had a bucket split. Add the new bucket here.
                    await AddItemToNodeAsync(spot, addedItem.up_key, addedItem.up_value, addedItem.up_node, addedItem).ConfigureAwait(false);
                }
            }
        }
Пример #2
0
        public async Task AddItemAsync(T new_key, int[] new_value)
        {
            if (this.Root.OID == 0)
            {
                await this.Root.PersistAsync().ConfigureAwait(false);
            }
            AddedItem <T> addedItem = new AddedItem <T>();
            await Root.AddItemAsync(new_key, new_value, addedItem).ConfigureAwait(false);

            // See if there was a root bucket split.
            if (addedItem.up_node != null)
            {
                BTreeNode <T> new_root = new BTreeNode <T>(siaqodb, this);

                new_root.Keys[0]     = addedItem.up_key;
                new_root.Values[0]   = addedItem.up_value;
                new_root.Children[0] = Root;
                new_root.Children[1] = addedItem.up_node;
                new_root.NumKeysUsed = 1;

                Root = new_root;
                await new_root.PersistAsync().ConfigureAwait(false);
            }
        }
Пример #3
0
        private async Task SplitNodeAsync(int spot, T new_key, int[] new_value, BTreeNode <T> new_child, AddedItem <T> addedItem)
        {
            // Make arrays holding all of the keys, values, and children.
            T[] new_keys = new T[KEYS_PER_NODE + 1];
            Array.Copy(this.Keys, 0, new_keys, 0, spot);
            new_keys[spot] = new_key;
            Array.Copy(this.Keys, spot, new_keys, spot + 1, KEYS_PER_NODE - spot);

            int[][] new_values = new int[KEYS_PER_NODE + 1][];
            Array.Copy(this.Values, 0, new_values, 0, spot);
            new_values[spot] = new_value;
            Array.Copy(this.Values, spot, new_values, spot + 1, KEYS_PER_NODE - spot);

            BTreeNode <T>[] new_children = new BTreeNode <T> [CHILDREN_PER_NODE + 1];
            Array.Copy(this.Children, 0, new_children, 0, spot + 1);
            new_children[spot + 1] = new_child;
            Array.Copy(this.Children, spot + 1, new_children, spot + 2, KEYS_PER_NODE - spot);

            // Copy the first half of the items into this node.
            Array.Copy(new_keys, 0, this.Keys, 0, HALF_NUM_KEYS);
            Array.Copy(new_values, 0, this.Values, 0, HALF_NUM_KEYS);
            Array.Copy(new_children, 0, this.Children, 0, HALF_NUM_KEYS + 1);
            Array.Clear(this.Keys, HALF_NUM_KEYS, HALF_NUM_KEYS);
            Array.Clear(this.Values, HALF_NUM_KEYS, HALF_NUM_KEYS);
            Array.Clear(this.Children, HALF_NUM_KEYS + 1, HALF_NUM_KEYS);
            this.NumKeysUsed = HALF_NUM_KEYS;

            // Set the up key and value.
            addedItem.up_key   = new_keys[HALF_NUM_KEYS];
            addedItem.up_value = new_values[HALF_NUM_KEYS];

            // Make the new node to pass up.
            addedItem.up_node = new BTreeNode <T>(this.siaqodb, this.btree);
            Array.Copy(new_keys, HALF_NUM_KEYS + 1, addedItem.up_node.Keys, 0, HALF_NUM_KEYS);
            Array.Copy(new_values, HALF_NUM_KEYS + 1, addedItem.up_node.Values, 0, HALF_NUM_KEYS);
            Array.Copy(new_children, HALF_NUM_KEYS + 1, addedItem.up_node.Children, 0, HALF_NUM_KEYS + 1);
            addedItem.up_node.NumKeysUsed = HALF_NUM_KEYS;

            await this.PersistAsync().ConfigureAwait(false);

            await addedItem.up_node.PersistAsync().ConfigureAwait(false);
        }
Пример #4
0
        // Add the new item to this node, if it fits.
        private async Task AddItemToNodeAsync(int spot, T new_key, int[] new_value, BTreeNode <T> new_child, AddedItem <T> addedItem)
        {
            // See if we have room.
            if (NumKeysUsed < KEYS_PER_NODE)
            {
                // There is room here.
                await AddItemInNodeWithRoomAsync(spot, new_key, new_value, new_child).ConfigureAwait(false);

                addedItem.up_key   = default(T);
                addedItem.up_value = null;
                addedItem.up_node  = null;
            }
            else
            {
                // There is no room here.
                await SplitNodeAsync(spot, new_key, new_value, new_child, addedItem).ConfigureAwait(false);
            }
        }