Beispiel #1
0
        /* Helper */

        private int SearchKey(long key)
        {
            int keyCount = TreeNode.KeyCount(_cursor);

            TreeNode.Type type = TreeNode.IsInternal(_cursor) ? INTERNAL : LEAF;
            _searchKey.Value = key;
            return(search(_cursor, _node, type, _searchKey, _readKey, keyCount));
        }
Beispiel #2
0
        /// <summary>
        /// Search for left most pos such that keyAtPos obeys key <= keyAtPos.
        /// Return pos (not offset) of keyAtPos, or key count if no such key exist.
        /// <para>
        /// On insert, key should be inserted at pos.
        /// On seek in internal, child at pos should be followed from internal node.
        /// On seek in leaf, value at pos is correct if keyAtPos is equal to key.
        /// </para>
        /// <para>
        /// Implemented as binary search.
        /// </para>
        /// <para>
        /// Leaves cursor on same page as when called. No guarantees on offset.
        ///
        /// </para>
        /// </summary>
        /// <param name="cursor"> <seealso cref="PageCursor"/> pinned to page with node (internal or leaf does not matter) </param>
        /// <param name="bTreeNode"> <seealso cref="TreeNode"/> that knows how to operate on KEY and VALUE </param>
        /// <param name="type"> <seealso cref="TreeNode.Type"/> of this tree node being searched </param>
        /// <param name="key"> KEY to search for </param>
        /// <param name="readKey"> KEY to use as temporary storage during calculation. </param> </param>
        /// <param name="keyCount"> number of keys in node when starting search    <returns> search result where least significant 31 bits are first position i for which
        /// bTreeNode.keyComparator().compare( key, bTreeNode.keyAt( i ) <= 0, or keyCount if no such key exists.
        /// highest bit (sign bit) says whether or not the exact key was found in the node, if so set to 1, otherwise 0.
        /// To extract position from the returned search result, then use <seealso cref="positionOf(int)"/>.
        /// To extract whether or not the exact key was found, then use <seealso cref="isHit(int)"/>. </returns>
        internal static int Search <KEY, VALUE>(PageCursor cursor, TreeNode <KEY, VALUE> bTreeNode, TreeNode.Type type, KEY key, KEY readKey, int keyCount)
        {
            if (keyCount == 0)
            {
                return(SearchResult(0, false));
            }

            int  lower  = 0;
            int  higher = keyCount - 1;
            int  pos;
            bool hit = false;

            // Compare key with lower and higher and sort out special cases
            IComparer <KEY> comparator = bTreeNode.KeyComparator();
            int             comparison;

            // key greater than greatest key in node
            if (comparator.Compare(key, bTreeNode.KeyAt(cursor, readKey, higher, type)) > 0)
            {
                pos = keyCount;
            }
            // key smaller than or equal to smallest key in node
            else if ((comparison = comparator.Compare(key, bTreeNode.KeyAt(cursor, readKey, lower, type))) <= 0)
            {
                if (comparison == 0)
                {
                    hit = true;
                }
                pos = 0;
            }
            else
            {
                // Start binary search
                // If key <= keyAtPos -> move higher to pos
                // If key > keyAtPos -> move lower to pos+1
                // Terminate when lower == higher
                while (lower < higher)
                {
                    pos        = (lower + higher) / 2;
                    comparison = comparator.Compare(key, bTreeNode.KeyAt(cursor, readKey, pos, type));
                    if (comparison <= 0)
                    {
                        higher = pos;
                    }
                    else
                    {
                        lower = pos + 1;
                    }
                }
                if (lower != higher)
                {
                    return(NO_SUCCESS_FLAG);
                }
                pos = lower;

                hit = comparator.Compare(key, bTreeNode.KeyAt(cursor, readKey, pos, type)) == 0;
            }
            return(SearchResult(pos, hit));
        }