コード例 #1
0
        public Row RequestRow(IServerProcess AProcess, Schema.IRowType ARowType, NativeRow ARow)
        {
            Row LRow = GetRow();

            LRow.Open(AProcess, ARowType, ARow);
            return(LRow);
        }
コード例 #2
0
        /// <summary>
        /// The recursive portion of the find key algorithm invoked by the FindKey method of the parent Index.
        /// </summary>
        public bool FindKey(Schema.IRowType keyRowType, NativeRow key, RowTreeSearchPath rowTreeSearchPath, out int entryNumber)
        {
            rowTreeSearchPath.Add(this);
            if (Node.NodeType == NativeRowTreeNodeType.Routing)
            {
                // Perform a binary search among the keys in this node to determine which streamid to follow for the next node
                bool result = NodeSearch(keyRowType, key, out entryNumber);

                // If the key was found, use the given entry number, otherwise, use the one before the given entry
                entryNumber = result ? entryNumber : (entryNumber - 1);
                return
                    (new RowTreeNode
                     (
                         Manager,
                         Tree,
                         RoutingNode.Nodes[entryNumber],
                         LockMode.Shared
                     ).FindKey
                     (
                         keyRowType,
                         key,
                         rowTreeSearchPath,
                         out entryNumber
                     ));
            }
            else
            {
                // Perform a binary search among the keys in this node to determine which entry, if any, is equal to the given key
                return(NodeSearch(keyRowType, key, out entryNumber));
            }
        }
コード例 #3
0
ファイル: NativeRowMap.cs プロジェクト: laszlo-kiss/Dataphor
        internal IValueManager _manager;         // Only used during the Add and Remove calls

        public bool CompareEqual(IValueManager manager, NativeRow indexKey, NativeRow compareKey)
        {
            // If AIndexKeyRowType is null, the index key must have the structure of an index key,
            // Otherwise, the IndexKey row could be a subset of the actual index key.
            // In that case, AIndexKeyRowType is the RowType for the IndexKey row.
            // It is the caller's responsibility to ensure that the passed IndexKey RowType
            // is a subset of the actual IndexKey with order intact.
            //Row LIndexKey = new Row(AManager, AIndexKeyRowType, AIndexKey);

            // If ACompareContext is null, the compare key must have the structure of an index key,
            // Otherwise the CompareKey could be a subset of the actual index key.
            // In that case, ACompareContext is the RowType for the CompareKey row.
            // It is the caller's responsibility to ensure that the passed CompareKey RowType
            // is a subset of the IndexKey with order intact.
            //Row LCompareKey = new Row(AManager, ACompareKeyRowType, ACompareKey);

            for (int index = 0; index < _keyRowType.Columns.Count; index++)
            {
                if (index >= compareKey.Values.Count())
                {
                    return(false);
                }

                if ((indexKey.Values[index] != null) && (compareKey.Values[index] != null))
                {
                    if (_keyRowType.Columns[index].DataType is Schema.ScalarType)
                    {
                        if (!manager.EvaluateEqualitySort(GetEqualitySort(Key.Columns[index].Name), indexKey.Values[index], compareKey.Values[index]))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        using (var indexValue = DataValue.FromNative(manager, indexKey.DataTypes[index], indexKey.Values[index]))
                        {
                            using (var compareValue = DataValue.FromNative(manager, compareKey.DataTypes[index], compareKey.Values[index]))
                            {
                                if (!manager.EvaluateEqualitySort(GetEqualitySort(Key.Columns[index].Name), indexValue, compareValue))
                                {
                                    return(false);
                                }
                            }
                        }
                    }
                }
                else if (indexKey.Values[index] != null)
                {
                    return(false);
                }
                else if (compareKey.Values[index] != null)
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #4
0
 public Row(IValueManager manager, Schema.IRowType dataType) : base(manager, dataType)
 {
     _row = new NativeRow(DataType.Columns.Count);
                 #if USEDATATYPESINNATIVEROW
     for (int index = 0; index < DataType.Columns.Count; index++)
     {
         _row.DataTypes[index] = DataType.Columns[index].DataType;
     }
                 #endif
     ValuesOwned = true;
 }
コード例 #5
0
ファイル: NativeRowMap.cs プロジェクト: laszlo-kiss/Dataphor
 private void InternalAdd(IValueManager manager, NativeRow key, NativeRow data)
 {
     _manager = manager;
     try
     {
         _rows.Add(key, data);
     }
     finally
     {
         _manager = null;
     }
 }
コード例 #6
0
ファイル: NativeRowMap.cs プロジェクト: laszlo-kiss/Dataphor
 private void InternalRemove(IValueManager manager, NativeRow key)
 {
     _manager = manager;
     try
     {
         _rows.Remove(key);
     }
     finally
     {
         _manager = null;
     }
 }
コード例 #7
0
        public void Insert(NativeRow key, NativeRow row, int entryNumber)
        {
            // Slide all entries above the insert index
            Array.Copy(_keys, entryNumber, _keys, entryNumber + 1, _entryCount - entryNumber);
            Array.Copy(_rows, entryNumber, _rows, entryNumber + 1, _entryCount - entryNumber);

            // Set the new entry data
            _keys[entryNumber] = key;
            _rows[entryNumber] = row;

            // Increment entry count
            _entryCount++;
        }
コード例 #8
0
        public void Insert(NativeRow key, NativeRowTreeNode node, int entryNumber)
        {
            // Slide all entries above the insert index
            Array.Copy(_keys, entryNumber, _keys, entryNumber + 1, _entryCount - entryNumber);
            Array.Copy(_nodes, entryNumber, _nodes, entryNumber + 1, _entryCount - entryNumber);

            // Set the new entry data
            _keys[entryNumber]  = key;
            _nodes[entryNumber] = node;

            // Increment entry count
            _entryCount++;
        }
コード例 #9
0
ファイル: NativeRowMap.cs プロジェクト: laszlo-kiss/Dataphor
 private NativeRow InternalGet(IValueManager manager, NativeRow key)
 {
     _manager = manager;
     try
     {
         NativeRow result;
         _rows.TryGetValue(key, out result);
         return(result);
     }
     finally
     {
         _manager = null;
     }
 }
コード例 #10
0
        private bool FindIndexKey(Schema.IRowType keyRowType, NativeRow key, out RowTreeNode indexNode, out int entryNumber)
        {
            RowTreeSearchPath searchPath = new RowTreeSearchPath();

            try
            {
                bool result = _accessPath.FindKey(_manager, keyRowType, key, searchPath, out entryNumber);
                indexNode = searchPath.DisownAt(searchPath.Count - 1);
                return(result);
            }
            finally
            {
                searchPath.Dispose();
            }
        }
コード例 #11
0
        // TODO: Asynchronous collapsed node recovery
        /// <summary>Deletes the entry given by AKey.  The streams are disposed through the DisposeKey event, so it is the responsibility of the index user to dispose references within the streams.</summary>
        public override void Delete(IValueManager manager, NativeRow key)
        {
            int entryNumber;

            using (RowTreeSearchPath rowTreeSearchPath = new RowTreeSearchPath())
            {
                bool result = FindKey(manager, KeyRowType, key, rowTreeSearchPath, out entryNumber);
                if (!result)
                {
                    throw new IndexException(IndexException.Codes.KeyNotFound);
                }

                InternalDelete(manager, rowTreeSearchPath, entryNumber);
            }
        }
コード例 #12
0
        /// <summary>
        /// The given streams are copied into the index, so references within the streams
        /// are considered owned by the index after the insert.
        /// </summary>
        public override void Insert(IValueManager manager, NativeRow key, NativeRow data)
        {
            int entryNumber;

            using (RowTreeSearchPath rowTreeSearchPath = new RowTreeSearchPath())
            {
                bool result = FindKey(manager, KeyRowType, key, rowTreeSearchPath, out entryNumber);
                if (result)
                {
                    throw new IndexException(IndexException.Codes.DuplicateKey);
                }

                InternalInsert(manager, rowTreeSearchPath, entryNumber, key, data);
            }
        }
コード例 #13
0
ファイル: NativeRowMap.cs プロジェクト: laszlo-kiss/Dataphor
        public override void Update(IValueManager manager, NativeRow oldKey, NativeRow newKey, NativeRow newData)
        {
            var oldData = InternalGet(manager, oldKey);

            if (newData != null)
            {
                DisposeData(manager, oldData);
            }
            else
            {
                newData = oldData;
            }
            DisposeKey(manager, oldKey);
            InternalRemove(manager, oldKey);

            InternalAdd(manager, newKey, newData);
        }
コード例 #14
0
        public override object CopyNativeAs(Schema.IDataType dataType)
        {
            if (_row == null)
            {
                return(null);
            }

            if (Object.ReferenceEquals(DataType, dataType))
            {
                NativeRow newRow = new NativeRow(DataType.Columns.Count);
                if (_row != null)
                {
                    for (int index = 0; index < DataType.Columns.Count; index++)
                    {
                                                #if USEDATATYPESINNATIVEROW
                        newRow.DataTypes[index] = _row.DataTypes[index];
                        newRow.Values[index]    = CopyNative(Manager, _row.DataTypes[index], _row.Values[index]);
                                                #else
                        newRow.Values[index] = CopyNative(Manager, DataType.Columns[index].DataType, FRow.Values[index]);
                                                #endif
                    }
                }
                return(newRow);
            }
            else
            {
                NativeRow newRow           = new NativeRow(DataType.Columns.Count);
                Schema.IRowType newRowType = (Schema.IRowType)dataType;
                if (_row != null)
                {
                    for (int index = 0; index < DataType.Columns.Count; index++)
                    {
                        int newIndex = newRowType.Columns.IndexOfName(DataType.Columns[index].Name);
                                                #if USEDATATYPESINNATIVEROW
                        newRow.DataTypes[newIndex] = _row.DataTypes[index];
                        newRow.Values[newIndex]    = CopyNative(Manager, _row.DataTypes[index], _row.Values[index]);
                                                #else
                        newRow.Values[newIndex] = CopyNative(Manager, DataType.Columns[index].DataType, FRow.Values[index]);
                                                #endif
                    }
                }
                return(newRow);
            }
        }
コード例 #15
0
ファイル: DataValue.cs プロジェクト: laszlo-kiss/Dataphor
        public static void DisposeValue(IValueManager manager, object tempValue)
        {
            IDataValue localTempValue = tempValue as IDataValue;

            if (localTempValue != null)
            {
                localTempValue.Dispose();
                return;
            }

            if (tempValue is StreamID)
            {
                manager.StreamManager.Deallocate((StreamID)tempValue);
                return;
            }

            NativeRow nativeRow = tempValue as NativeRow;

            if (nativeRow != null)
            {
                for (int index = 0; index < nativeRow.Values.Length; index++)
                {
                    DisposeValue(manager, nativeRow.Values[index]);
                }
                return;
            }

            NativeList nativeList = tempValue as NativeList;

            if (nativeList != null)
            {
                for (int index = 0; index < nativeList.Values.Count; index++)
                {
                    DisposeValue(manager, nativeList.Values[index]);
                }
            }

            NativeTable nativeTable = tempValue as NativeTable;

            if (nativeTable != null)
            {
                DisposeNative(manager, nativeTable.TableType, nativeTable);
            }
        }
コード例 #16
0
        /// <summary>Updates the entry given by AOldKey to the entry given by ANewKey and ANewData.  If AOldKey == ANewKey, the data for the entry is updated in place, otherwise it is moved to the location given by ANewKey.</summary>
        public override void Update(IValueManager manager, NativeRow oldKey, NativeRow newKey, NativeRow newData)
        {
            int entryNumber;

            using (RowTreeSearchPath rowTreeSearchPath = new RowTreeSearchPath())
            {
                bool result = FindKey(manager, KeyRowType, oldKey, rowTreeSearchPath, out entryNumber);
                if (!result)
                {
                    throw new IndexException(IndexException.Codes.KeyNotFound);
                }

                if (Compare(manager, KeyRowType, oldKey, KeyRowType, newKey) == 0)
                {
                    if (newData != null)
                    {
                        rowTreeSearchPath.DataNode.UpdateData(newData, entryNumber);
                    }
                }
                else
                {
                    if (newData == null)
                    {
                        newData = rowTreeSearchPath.DataNode.DataNode.Rows[entryNumber];
                        rowTreeSearchPath.DataNode.DataNode.Delete(entryNumber);                         // Don't dispose here this is a move
                    }
                    else
                    {
                        InternalDelete(manager, rowTreeSearchPath, entryNumber);                         // Dispose here this is not a move
                    }
                    rowTreeSearchPath.Dispose();
                    result = FindKey(manager, KeyRowType, newKey, rowTreeSearchPath, out entryNumber);
                    if (result)
                    {
                        throw new IndexException(IndexException.Codes.DuplicateKey);
                    }

                    InternalInsert(manager, rowTreeSearchPath, entryNumber, newKey, newData);
                }
            }
        }
コード例 #17
0
        /// <summary>
        /// Performs a binary search among the entries in this node for the given key.  Will always return an
        /// entry index in AEntryNumber, which is the index of the entry that was found if the method returns true,
        /// otherwise it is the index where the key should be inserted if the method returns false.
        /// </summary>
        public bool NodeSearch(Schema.IRowType keyRowType, NativeRow key, out int entryNumber)
        {
            int lo     = (Node.NodeType == NativeRowTreeNodeType.Routing ? 1 : 0);
            int hi     = Node.EntryCount - 1;
            int index  = 0;
            int result = -1;

            while (lo <= hi)
            {
                index  = (lo + hi) / 2;
                result = Tree.Compare(Manager, Tree.KeyRowType, Node.Keys[index], keyRowType, key);
                if (result == 0)
                {
                    break;
                }
                else if (result > 0)
                {
                    hi = index - 1;
                }
                else                 // if (LResult < 0) unnecessary
                {
                    lo = index + 1;
                }
            }

            if (result == 0)
            {
                entryNumber = index;
            }
            else
            {
                entryNumber = lo;
            }

            return(result == 0);
        }
コード例 #18
0
ファイル: NativeRowMap.cs プロジェクト: laszlo-kiss/Dataphor
 public override void Insert(IValueManager manager, NativeRow key, NativeRow data)
 {
     InternalAdd(manager, key, data);
 }
コード例 #19
0
 public NativeRowTreeRoutingNode(NativeRowTree nativeRowTree) : base(nativeRowTree)
 {
     _nodeType = NativeRowTreeNodeType.Routing;
     _keys     = new NativeRow[_nativeRowTree.Fanout];
     _nodes    = new NativeRowTreeNode[_nativeRowTree.Fanout];
 }
コード例 #20
0
        public int Compare(IValueManager manager, Schema.IRowType indexKeyRowType, NativeRow indexKey, Schema.IRowType compareKeyRowType, NativeRow compareKey)
        {
            // If AIndexKeyRowType is null, the index key must have the structure of an index key,
            // Otherwise, the IndexKey row could be a subset of the actual index key.
            // In that case, AIndexKeyRowType is the RowType for the IndexKey row.
            // It is the caller's responsibility to ensure that the passed IndexKey RowType
            // is a subset of the actual IndexKey with order intact.
            //Row LIndexKey = new Row(AManager, AIndexKeyRowType, AIndexKey);

            // If ACompareContext is null, the compare key must have the structure of an index key,
            // Otherwise the CompareKey could be a subset of the actual index key.
            // In that case, ACompareContext is the RowType for the CompareKey row.
            // It is the caller's responsibility to ensure that the passed CompareKey RowType
            // is a subset of the IndexKey with order intact.
            //Row LCompareKey = new Row(AManager, ACompareKeyRowType, ACompareKey);

            int result = 0;

            for (int index = 0; index < indexKeyRowType.Columns.Count; index++)
            {
                if (index >= compareKeyRowType.Columns.Count)
                {
                    break;
                }

                if ((indexKey.Values[index] != null) && (compareKey.Values[index] != null))
                {
                    if (indexKeyRowType.Columns[index].DataType is Schema.ScalarType)
                    {
                        result = manager.EvaluateSort(Key.Columns[index], indexKey.Values[index], compareKey.Values[index]);
                    }
                    else
                    {
                        using (var indexValue = DataValue.FromNative(manager, indexKey.DataTypes[index], indexKey.Values[index]))
                        {
                            using (var compareValue = DataValue.FromNative(manager, compareKey.DataTypes[index], compareKey.Values[index]))
                            {
                                result = manager.EvaluateSort(Key.Columns[index], indexValue, compareValue);
                            }
                        }
                    }
                }
                else if (indexKey.Values[index] != null)
                {
                    result = Key.Columns[index].Ascending ? 1 : -1;
                }
                else if (compareKey.Values[index] != null)
                {
                    result = Key.Columns[index].Ascending ? -1 : 1;
                }
                else
                {
                    result = 0;
                }

                if (result != 0)
                {
                    break;
                }
            }

            //LIndexKey.Dispose();
            //LCompareKey.Dispose();
            return(result);
        }
コード例 #21
0
 /// <summary>
 /// Searches for the given key within the index.  ARowTreeSearchPath and AEntryNumber together give the
 /// location of the key in the index.  If the search is successful, the entry exists, otherwise
 /// the EntryNumber indicates where the entry should be placed for an insert.
 /// </summary>
 /// <param name="key">The key to be found.</param>
 /// <param name="rowTreeSearchPath">A <see cref="RowTreeSearchPath"/> which will contain the set of nodes along the search path to the key.</param>
 /// <param name="entryNumber">The EntryNumber where the key either is, or should be, depending on the result of the find.</param>
 /// <returns>A boolean value indicating the success or failure of the find.</returns>
 public bool FindKey(IValueManager manager, Schema.IRowType keyRowType, NativeRow key, RowTreeSearchPath rowTreeSearchPath, out int entryNumber)
 {
     return(new RowTreeNode(manager, this, Root, LockMode.Shared).FindKey(keyRowType, key, rowTreeSearchPath, out entryNumber));
 }
コード例 #22
0
 /// <summary>Updates the entry given by AOldKey to the stream given by ANewKey.  The data for the entry is moved to the new location.</summary>
 public void Update(IValueManager manager, NativeRow oldKey, NativeRow newKey)
 {
     Update(manager, oldKey, newKey, null);
 }
コード例 #23
0
ファイル: NativeRowMap.cs プロジェクト: laszlo-kiss/Dataphor
 public override void Delete(IValueManager manager, NativeRow key)
 {
     DisposeData(manager, InternalGet(manager, key));
     DisposeKey(manager, key);
     InternalRemove(manager, key);
 }
コード例 #24
0
 public NativeRowTreeDataNode(NativeRowTree nativeRowTree) : base(nativeRowTree)
 {
     _nodeType = NativeRowTreeNodeType.Data;
     _keys     = new NativeRow[_nativeRowTree.Capacity];
     _rows     = new NativeRow[_nativeRowTree.Capacity];
 }
コード例 #25
0
ファイル: NativeRowMap.cs プロジェクト: laszlo-kiss/Dataphor
 public bool ContainsKey(IValueManager manager, NativeRow key)
 {
     return(InternalGet(manager, key) != null);
 }
コード例 #26
0
        public void InsertRouting(NativeRow key, NativeRowTreeNode node, int entryNumber)
        {
            RoutingNode.Insert(key, node, entryNumber);

            Tree.RowsMoved(Node, entryNumber, Node.EntryCount - 2, Node, 1);
        }
コード例 #27
0
        /// <summary>Inserts the given Key and Data streams into this node at the given index.</summary>
        public void InsertData(NativeRow key, NativeRow data, int entryNumber)
        {
            DataNode.Insert(key, data, entryNumber);

            Tree.RowsMoved(Node, entryNumber, Node.EntryCount - 2, Node, 1);
        }
コード例 #28
0
ファイル: ScalarValue.cs プロジェクト: laszlo-kiss/Dataphor
 public RowInternedScalar(IValueManager manager, Schema.IScalarType dataType, NativeRow nativeRow, int index) : base(manager, dataType)
 {
     _nativeRow = nativeRow;
     _index     = index;
 }
コード例 #29
0
 public void UpdateData(NativeRow data, int entryNumber)
 {
     Tree.DisposeData(Manager, DataNode.Rows[entryNumber]);
     DataNode.Rows[entryNumber] = data;
 }
コード例 #30
0
        private void InternalInsert(IValueManager manager, RowTreeSearchPath rowTreeSearchPath, int entryNumber, NativeRow key, NativeRow data)
        {
            // Walk back up the search path, inserting data and splitting pages as necessary
            RowTreeNode       newRowTreeNode;
            NativeRowTreeNode splitNode = null;

            for (int index = rowTreeSearchPath.Count - 1; index >= 0; index--)
            {
                if (rowTreeSearchPath[index].Node.EntryCount >= Capacity)
                {
                    // Allocate a new node
                    using (newRowTreeNode = AllocateNode(manager, rowTreeSearchPath[index].Node.NodeType))
                    {
                        // Thread it into the list of leaves, if necessary
                        if (newRowTreeNode.Node.NodeType == NativeRowTreeNodeType.Data)
                        {
                            newRowTreeNode.Node.PriorNode          = rowTreeSearchPath[index].Node;
                            newRowTreeNode.Node.NextNode           = rowTreeSearchPath[index].Node.NextNode;
                            rowTreeSearchPath[index].Node.NextNode = newRowTreeNode.Node;
                            if (newRowTreeNode.Node.NextNode == null)
                            {
                                Tail = newRowTreeNode.Node;
                            }
                            else
                            {
                                using (RowTreeNode nextRowTreeNode = new RowTreeNode(manager, this, newRowTreeNode.Node.NextNode, LockMode.Exclusive))
                                {
                                    nextRowTreeNode.Node.PriorNode = newRowTreeNode.Node;
                                }
                            }
                        }

                        int entryPivot = Split(rowTreeSearchPath[index].Node, newRowTreeNode.Node);

                        // Insert the new entry into the appropriate node
                        if (entryNumber >= entryPivot)
                        {
                            if (newRowTreeNode.Node.NodeType == NativeRowTreeNodeType.Data)
                            {
                                newRowTreeNode.InsertData(key, data, entryNumber - entryPivot);
                            }
                            else
                            {
                                newRowTreeNode.InsertRouting(key, splitNode, entryNumber - entryPivot);
                            }
                        }
                        else
                        if (newRowTreeNode.Node.NodeType == NativeRowTreeNodeType.Data)
                        {
                            rowTreeSearchPath[index].InsertData(key, data, entryNumber);
                        }
                        else
                        {
                            rowTreeSearchPath[index].InsertRouting(key, splitNode, entryNumber);
                        }

                        // Reset the AKey for the next round
                        // The key for the entry one level up is the first key for the newly allocated node
                        key = CopyKey(manager, newRowTreeNode.Node.Keys[0]);

                        // Set LSplitNode to the newly allocated node
                        splitNode = newRowTreeNode.Node;
                    }

                    if (index == 0)
                    {
                        // Allocate a new root node and grow the height of the tree by 1
                        using (newRowTreeNode = AllocateNode(manager, NativeRowTreeNodeType.Routing))
                        {
                            newRowTreeNode.InsertRouting(null, rowTreeSearchPath[index].Node, 0);                             // 1st key of a routing node is not used
                            newRowTreeNode.InsertRouting(key, splitNode, 1);
                            Root = newRowTreeNode.Node;
                            Height++;
                        }
                    }
                    else
                    {
                        // reset AEntryNumber for the next round
                        bool result = rowTreeSearchPath[index - 1].NodeSearch(KeyRowType, key, out entryNumber);

                        // At this point we should be guaranteed to have a routing key which does not exist in the parent node
                        if (result)
                        {
                            throw new IndexException(IndexException.Codes.DuplicateRoutingKey);
                        }
                    }
                }
                else
                {
                    if (rowTreeSearchPath[index].Node.NodeType == NativeRowTreeNodeType.Data)
                    {
                        rowTreeSearchPath[index].InsertData(key, data, entryNumber);
                    }
                    else
                    {
                        rowTreeSearchPath[index].InsertRouting(key, splitNode, entryNumber);
                    }
                    break;
                }
            }
        }