// 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(); }
public uint GetHeapIndexSize(StreamID streamID) { CheckDisposed(); if (m_metadataTableHeader == null) { throw new InvalidOperationException("Missing metadata table header."); } return(m_metadataTableHeader->GetHeapIndexSize(streamID)); }
/// <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; } }
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); }
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); }
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(); } }
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); }
/// <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)); }
//# 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"); } }
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); } }
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); } }
internal StreamMeta(StreamID id) { ID = id; }
public IRemoteStream OpenRemote(StreamID streamID, LockMode mode) { return((IRemoteStream)Open(streamID, mode)); }
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; } } }
/// <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; }
void IStreamManager.Close(StreamID AStreamID) { StreamManager.Close(AStreamID); }
Stream IStreamManager.Open(StreamID streamID, LockMode lockMode) { return(StreamManager.Open(streamID, lockMode)); }
StreamID IStreamManager.Reference(StreamID streamID) { return(StreamManager.Reference(streamID)); }
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; } } }
public void RowsMoved(StreamID AOldStreamID, int AOldEntryNumberMin, int AOldEntryNumberMax, StreamID ANewStreamID, int AEntryNumberDelta) { if (OnRowsMoved != null) { OnRowsMoved(this, AOldStreamID, AOldEntryNumberMin, AOldEntryNumberMax, ANewStreamID, AEntryNumberDelta); } }
void IStreamManager.Deallocate(StreamID streamID) { StreamManager.Deallocate(streamID); }
//# 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"); } }
IRemoteStream IStreamManager.OpenRemote(StreamID streamID, LockMode lockMode) { return(StreamManager.OpenRemote(streamID, lockMode)); }
internal StreamMeta(StreamID id) { ID = id;}
public static uint IndexSize(this StreamID id, PEFile peFile) { return(peFile.CheckNotNull("peFile").GetHeapIndexSize(id)); }
public Scalar(IValueManager manager, Schema.IScalarType dataType, StreamID streamID) : base(manager, dataType) { _streamID = streamID; ValuesOwned = false; }