Пример #1
0
 // Newly allocated stream IndexNode constructor
 public IndexNode(ServerProcess AProcess, Index AIndex, StreamID AStreamID, Stream AStream, IndexNodeType ANodeType)
 {
     FProcess  = AProcess;
     FIndex    = AIndex;
     FStreamID = AStreamID;
     FStream   = AStream;
     NodeType  = ANodeType;
     InternalInitialize();
 }
Пример #2
0
 public uint GetHeapIndexSize(StreamID streamID)
 {
     CheckDisposed();
     if (m_metadataTableHeader == null)
     {
         throw new InvalidOperationException("Missing metadata table header.");
     }
     return(m_metadataTableHeader->GetHeapIndexSize(streamID));
 }
Пример #3
0
 /// <summary>Create is only called once to create a new stored instance of the index.</summary>
 public void Create(ServerProcess AProcess)
 {
     using (IndexNode LIndexNode = AllocateNode(AProcess, IndexNodeType.Data))
     {
         FRootID = LIndexNode.StreamID;
         FHeadID = FRootID;
         FTailID = FRootID;
         FHeight = 1;
     }
 }
Пример #4
0
        public static unsafe void SetStreamID(Stream AStream, long AOffset, StreamID AStreamID)
        {
            byte[] LBuffer = new byte[sizeof(StreamID)];
            fixed(byte *LBufferPtr = &(LBuffer[0]))
            {
                *((StreamID *)LBufferPtr) = AStreamID;
            }

            AStream.Position = AOffset;
            AStream.Write(LBuffer, 0, LBuffer.Length);
        }
Пример #5
0
        public static void StartStream(Config config, StreamID id, String ipaddress)
        {
            int           cmd  = (int)SocketCommand.SOCKET_CMD_ENABLE_OUTPUT_STREAM | (int)id;
            SocketCommand scmd = (SocketCommand)cmd;

            byte[] duration = { 0, 0 };   // Indefinitely
            byte[] addr     = Encoding.ASCII.GetBytes(ipaddress);
            byte[] data     = duration.Concat(addr).ToArray();

            SendCommand(config, scmd, data, false);
        }
Пример #6
0
        private void IndexRowsMoved(Index AIndex, StreamID AOldStreamID, int AOldEntryNumberMin, int AOldEntryNumberMax, StreamID ANewStreamID, int AEntryNumberDelta)
        {
            if ((FIndexNode.StreamID == AOldStreamID) && (FEntryNumber >= AOldEntryNumberMin) && (FEntryNumber <= AOldEntryNumberMax))
            {
                if (AOldStreamID != ANewStreamID)
                {
                    SetIndexNode(new IndexNode(FProcess, FIndexNode.Index, ANewStreamID));
                }

                FEntryNumber += AEntryNumberDelta;
                UpdateScanPointer();
            }
        }
Пример #7
0
        private void DeallocateNode(ServerProcess AProcess, StreamID AStreamID)
        {
            using (IndexNode LIndexNode = new IndexNode(AProcess, this, AStreamID))
            {
                for (int LEntryIndex = LIndexNode.EntryCount - 1; LEntryIndex >= 0; LEntryIndex--)
                {
                    if (LIndexNode.NodeType == IndexNodeType.Routing)
                    {
                        if (LEntryIndex > 0)
                        {
                            DisposeKey(AProcess, LIndexNode.Key(LEntryIndex));
                        }
                        DeallocateNode(AProcess, IndexUtility.GetStreamID(LIndexNode.Data(LEntryIndex), 0));
                    }
                    else
                    {
                        DisposeKey(AProcess, LIndexNode.Key(LEntryIndex));
                        DisposeData(AProcess, LIndexNode.Data(LEntryIndex));

                        if (LIndexNode.NextNode == StreamID.Null)
                        {
                            FTailID = LIndexNode.PriorNode;
                        }
                        else
                        {
                            using (IndexNode LNextNode = new IndexNode(AProcess, this, LIndexNode.NextNode))
                            {
                                LNextNode.PriorNode = LIndexNode.PriorNode;
                            }
                        }

                        if (LIndexNode.PriorNode == StreamID.Null)
                        {
                            FHeadID = LIndexNode.NextNode;
                        }
                        else
                        {
                            using (IndexNode LPriorNode = new IndexNode(AProcess, this, LIndexNode.PriorNode))
                            {
                                LPriorNode.NextNode = LIndexNode.NextNode;
                            }
                        }
                    }
                }
            }

            AProcess.StreamManager.Deallocate(AStreamID);
        }
Пример #8
0
        /// <summary>
        /// Will return an IndexNode wrapper on a newly allocated IndexNode stream opened in exclusive mode
        /// it is the callers responsibility Dispose the returned IndexNode, closing and unlocking the stream
        /// </summary>
        private unsafe IndexNode AllocateNode(ServerProcess AProcess, IndexNodeType ANodeType)
        {
            // Allocate a new index node
            StreamID LStreamID = AProcess.StreamManager.Allocate();
            Stream   LStream   = AProcess.StreamManager.Open(LStreamID, LockMode.Shared);

            // Size it (HeaderSize + ((KeyLength + DataLength | sizeof(StreamID)) * Capacity | Fanout)
            if (ANodeType == IndexNodeType.Routing)
            {
                LStream.SetLength(checked (IndexNode.HeaderSize + ((KeyLength + sizeof(StreamID)) * Fanout)));
            }
            else
            {
                LStream.SetLength(checked (IndexNode.HeaderSize + ((KeyLength + DataLength) * Capacity)));
            }
            return(new IndexNode(AProcess, this, LStreamID, LStream, ANodeType));
        }
Пример #9
0
        //# Returns the number of bytes used to incode indexes into the given stream.
        //# If the number of entries in the provided stream is <= 2^16, this will be 2. Otherwise 4 will be returned.
        //#
        //# Throws
        //# =====================
        //# [ArgumentOutOfRangeException] : if the provided stream is not any of the following:
        //#     1. [StreamID.Strings]
        //#     2. [StreamID.Guid]
        //#     3. [StreamID.Blob]
        public uint GetHeapIndexSize(StreamID id)
        {
            switch (id)
            {
            case StreamID.Strings:
                return((HeapSizes & 0x1) != 0 ? 4u : 2u);

            case StreamID.Guid:
                return((HeapSizes & 0x2) != 0 ? 4u : 2u);

            case StreamID.Blob:
                return((HeapSizes & 0x4) != 0 ? 4u : 2u);

            default:
                throw new ArgumentOutOfRangeException("id", "Not a valid heap");
            }
        }
Пример #10
0
 public Stream Open(StreamID streamID, LockMode mode)
 {
     try
     {
         var          channel = GetServiceInterface();
         IAsyncResult result  = channel.BeginOpenStream(ProcessHandle, streamID, mode, null, null);
         result.AsyncWaitHandle.WaitOne();
         return(new ClientStream(this, channel.EndOpenStream(result)));
     }
     catch (FaultException <DataphorFault> fault)
     {
         throw DataphorFaultUtility.FaultToException(fault.Detail);
     }
     catch (CommunicationException ce)
     {
         ReportCommunicationError();
         throw new ServerException(ServerException.Codes.CommunicationFailure, ErrorSeverity.Environment, ce);
     }
 }
Пример #11
0
 public void Deallocate(StreamID streamID)
 {
     try
     {
         var          channel = GetServiceInterface();
         IAsyncResult result  = channel.BeginDeallocateStream(ProcessHandle, streamID, null, null);
         result.AsyncWaitHandle.WaitOne();
         channel.EndDeallocateStream(result);
     }
     catch (FaultException <DataphorFault> fault)
     {
         throw DataphorFaultUtility.FaultToException(fault.Detail);
     }
     catch (CommunicationException ce)
     {
         ReportCommunicationError();
         throw new ServerException(ServerException.Codes.CommunicationFailure, ErrorSeverity.Environment, ce);
     }
 }
Пример #12
0
 internal StreamMeta(StreamID id)
 {
     ID = id;
 }
Пример #13
0
 public IRemoteStream OpenRemote(StreamID streamID, LockMode mode)
 {
     return((IRemoteStream)Open(streamID, mode));
 }
Пример #14
0
        public override void ReadFromPhysical(byte[] buffer, int offset)
        {
            // Clear current value
            if (ValuesOwned && !IsNative && (StreamID != StreamID.Null))
            {
                Manager.StreamManager.Deallocate(StreamID);
            }

            // Read scalar header
            byte header = buffer[offset];

            offset++;
            if ((header & 1) != 0)             // if not nil
            {
                if ((header & 2) != 0)
                {
                    if (DataType.IsCompound)
                    {
                        using (IRow row = (IRow)DataValue.FromPhysical(Manager, DataType.CompoundRowType, buffer, offset))
                        {
                            Value           = row.AsNative;
                            row.ValuesOwned = false;
                        }
                    }
                    else
                    {
                        Streams.IConveyor conveyor = Manager.GetConveyor(DataType);
                        if (conveyor.IsStreaming)
                        {
                            Stream stream = new MemoryStream(buffer, offset, buffer.Length - offset, false, true);
                            Value = conveyor.Read(stream);
                            stream.Close();
                        }
                        else
                        {
                            Value = conveyor.Read(buffer, offset);
                        }
                    }
                }
                else
                {
                    if ((header & 4) != 0)                     // if expanded form
                    {
                        Value = Manager.StreamManager.Allocate();
                        Stream stream = Manager.StreamManager.Open(StreamID, LockMode.Exclusive);
                        stream.Write(buffer, offset, buffer.Length - offset);
                        stream.Close();
                    }
                    else
                    {
                        Value = StreamID.Read(buffer, offset);
                    }
                }
            }
            else
            {
                if ((header & 2) != 0)
                {
                    Value = null;
                }
                else
                {
                    Value = StreamID.Null;
                }
            }
        }
Пример #15
0
 /// <summary>Drops the index and deallocates the streams associated with it.</summary>
 public void Drop(ServerProcess AProcess)
 {
     DeallocateNode(AProcess, FRootID);
     FRootID = StreamID.Null;
     FHeight = 0;
 }
Пример #16
0
 void IStreamManager.Close(StreamID AStreamID)
 {
     StreamManager.Close(AStreamID);
 }
Пример #17
0
 Stream IStreamManager.Open(StreamID streamID, LockMode lockMode)
 {
     return(StreamManager.Open(streamID, lockMode));
 }
Пример #18
0
 StreamID IStreamManager.Reference(StreamID streamID)
 {
     return(StreamManager.Reference(streamID));
 }
Пример #19
0
        private unsafe void InternalInsert(ServerProcess AProcess, SearchPath ASearchPath, int AEntryNumber, Stream AKey, Stream AData)
        {
            // Walk back up the search path, inserting data and splitting pages as necessary
            IndexNode LNewIndexNode;

            for (int LIndex = ASearchPath.Count - 1; LIndex >= 0; LIndex--)
            {
                if (ASearchPath[LIndex].EntryCount >= ASearchPath[LIndex].MaxEntries)
                {
                    // Allocate a new node
                    using (LNewIndexNode = AllocateNode(AProcess, ASearchPath[LIndex].NodeType))
                    {
                        // Thread it into the list of leaves, if necessary
                        if (LNewIndexNode.NodeType == IndexNodeType.Data)
                        {
                            LNewIndexNode.PriorNode      = ASearchPath[LIndex].StreamID;
                            LNewIndexNode.NextNode       = ASearchPath[LIndex].NextNode;
                            ASearchPath[LIndex].NextNode = LNewIndexNode.StreamID;
                            if (LNewIndexNode.NextNode == StreamID.Null)
                            {
                                FTailID = LNewIndexNode.StreamID;
                            }
                            else
                            {
                                using (IndexNode LNextIndexNode = new IndexNode(AProcess, this, LNewIndexNode.NextNode))
                                {
                                    LNextIndexNode.PriorNode = LNewIndexNode.StreamID;
                                }
                            }
                        }

                        // Insert the upper half of the entries from ASearchPath[LIndex] into the new index node
                        int LEntryCount = ASearchPath[LIndex].EntryCount;
                        int LEntryPivot = LEntryCount / 2;
                        for (int LEntryIndex = LEntryPivot; LEntryIndex < LEntryCount; LEntryIndex++)
                        {
                            LNewIndexNode.InternalInsert(ASearchPath[LIndex].Key(LEntryIndex), ASearchPath[LIndex].Data(LEntryIndex), LEntryIndex - LEntryPivot);                             // The internal call prevents the RowsMoved event from being fired
                        }
                        // Remove the upper half of the entries from ASearchPath[LIndex]
                        for (int LEntryIndex = LEntryCount - 1; LEntryIndex >= LEntryPivot; LEntryIndex--)
                        {
                            ASearchPath[LIndex].InternalDelete(LEntryIndex);                             // The internal call prevents the data inside from being passed to the DisposeXXX methods, and prevents the RowDeleted event from being fired
                        }
                        // Notify index clients of the data change
                        RowsMoved(ASearchPath[LIndex].StreamID, LEntryPivot, LEntryCount - 1, LNewIndexNode.StreamID, -LEntryPivot);

                        // Insert the new entry into the appropriate node
                        if (AEntryNumber >= LEntryPivot)
                        {
                            LNewIndexNode.Insert(AKey, AData, AEntryNumber - LEntryPivot);
                        }
                        else
                        {
                            ASearchPath[LIndex].Insert(AKey, AData, AEntryNumber);
                        }

                        // Reset the AKey, AData and AEntryNumber variables for the next round
                        // The key for the entry one level up is the first key for the newly allocated node
                        AKey = new MemoryStream(KeyLength);
                        AKey.SetLength(KeyLength);
                        CopyKey(AProcess, LNewIndexNode.Key(0), AKey);

                        // The data is the StreamID of the newly allocated node
                        AData = new MemoryStream(sizeof(StreamID));
                        IndexUtility.SetStreamID(AData, 0, LNewIndexNode.StreamID);
                    }

                    if (LIndex == 0)
                    {
                        // Allocate a new root node and grow the height of the tree by 1
                        using (LNewIndexNode = AllocateNode(AProcess, IndexNodeType.Routing))
                        {
                            LNewIndexNode.Insert(AKey, AData, 0);
                            AKey = new MemoryStream(KeyLength);
                            AKey.SetLength(KeyLength);
                            AData = new MemoryStream(DataLength);
                            AData.SetLength(KeyLength);
                            IndexUtility.SetStreamID(AData, 0, ASearchPath[LIndex].StreamID);
                            LNewIndexNode.Insert(AKey, AData, 0);
                            FRootID = LNewIndexNode.StreamID;
                            FHeight++;
                        }
                    }
                    else
                    {
                        bool LResult = ASearchPath[LIndex - 1].NodeSearch(AKey, null, out AEntryNumber);
                        // At this point we should be guaranteed to have a routing key which does not exist in the parent node
                        if (LResult)
                        {
                            throw new IndexException(IndexException.Codes.DuplicateRoutingKey);
                        }
                    }
                }
                else
                {
                    ASearchPath[LIndex].Insert(AKey, AData, AEntryNumber);
                    break;
                }
            }
        }
Пример #20
0
 public void RowsMoved(StreamID AOldStreamID, int AOldEntryNumberMin, int AOldEntryNumberMax, StreamID ANewStreamID, int AEntryNumberDelta)
 {
     if (OnRowsMoved != null)
     {
         OnRowsMoved(this, AOldStreamID, AOldEntryNumberMin, AOldEntryNumberMax, ANewStreamID, AEntryNumberDelta);
     }
 }
Пример #21
0
 void IStreamManager.Deallocate(StreamID streamID)
 {
     StreamManager.Deallocate(streamID);
 }
Пример #22
0
 //# Returns the number of bytes used to incode indexes into the given stream.
 //# If the number of entries in the provided stream is <= 2^16, this will be 2. Otherwise 4 will be returned.
 //#
 //# Throws
 //# =====================
 //# [ArgumentOutOfRangeException] : if the provided stream is not any of the following:
 //#     1. [StreamID.Strings]
 //#     2. [StreamID.Guid]
 //#     3. [StreamID.Blob]
 public uint GetHeapIndexSize(StreamID id)
 {
     switch (id) {
         case StreamID.Strings:
             return (HeapSizes & 0x1) != 0 ? 4u : 2u;
         case StreamID.Guid:
             return (HeapSizes & 0x2) != 0 ? 4u : 2u;
         case StreamID.Blob:
             return (HeapSizes & 0x4) != 0 ? 4u : 2u;
         default:
             throw new ArgumentOutOfRangeException("id","Not a valid heap");
     }
 }
Пример #23
0
 IRemoteStream IStreamManager.OpenRemote(StreamID streamID, LockMode lockMode)
 {
     return(StreamManager.OpenRemote(streamID, lockMode));
 }
Пример #24
0
 internal StreamMeta(StreamID id) { ID = id;}
Пример #25
0
 public static uint IndexSize(this StreamID id, PEFile peFile)
 {
     return(peFile.CheckNotNull("peFile").GetHeapIndexSize(id));
 }
Пример #26
0
 public Scalar(IValueManager manager, Schema.IScalarType dataType, StreamID streamID) : base(manager, dataType)
 {
     _streamID   = streamID;
     ValuesOwned = false;
 }