void LoadStream(StorageStreamMetadata metadata)
        {
            // Load segments
            this.metadata = metadata;
            long?segmentPosition = metadata.FirstSegmentPosition;

            segments.Clear();

            while (segmentPosition.HasValue)
            {
                Segment segment = Segment.Load(_storage.MasterStream, segmentPosition.Value);

                segments.AddLast(segment);
                segmentPosition = segment.NextLocation;
            }

            // Manually adjust stream length and initializedSized for stream table stream
            if (metadata.StreamId == SystemStreamId.StreamTable)
            {
                //metadata.Length = segments.Sum(x => x.DataAreaSize);
                long length = 0;
                foreach (var segment in segments)
                {
                    length += segment.DataAreaSize;
                }
                metadata.Length = length;

                metadata.InitializedLength = metadata.Length;
            }
        }
        /// <summary>
        /// Loads metadata
        /// </summary>
        public static StorageStreamMetadata Load(Stream streamTableStream, int streamTableIndex)
        {
            streamTableStream.Position = streamTableIndex * StorageStreamMetadata.StructureSize;
            streamTableStream.Read(Tools.Buffer, 0, StorageStreamMetadata.StructureSize);
            Tools.BufferReader.BaseStream.Position = 0;

            StorageStreamMetadata metadata = new StorageStreamMetadata(streamTableStream);

            metadata.StreamTableIndex  = streamTableIndex;
            metadata.StreamId          = new Guid(Tools.BufferReader.ReadBytes(16));
            metadata.Length            = Tools.BufferReader.ReadInt64();
            metadata.InitializedLength = Tools.BufferReader.ReadInt64();
            long firstSegmentPos = Tools.BufferReader.ReadInt64();

            metadata.FirstSegmentPosition = firstSegmentPos != 0 ? firstSegmentPos : (long?)null;
            metadata.Tag = Tools.BufferReader.ReadInt32();
            int hash           = Tools.BufferReader.ReadInt32();
            int calculatedHash = Tools.CalculateHash(metadata.StreamId, metadata.Length, metadata.InitializedLength, firstSegmentPos);

            if (hash != calculatedHash)
            {
                throw new StorageException("Error loading stream metadata");
            }

            return(metadata);
        }
Esempio n. 3
0
        void LoadStreamTable()
        {
            StorageStreamMetadata streamMetadata;

            stream.Position = 0;
            int index = 0;

            map.Clear();

            items.Clear();

            int cnt = (int)stream.Length / StorageStreamMetadata.StructureSize;

            for (int i = 0; i < cnt; i++)
            {
                streamMetadata = StorageStreamMetadata.Load(stream, i);

                if (streamMetadata.StreamId != Guid.Empty)
                {
                    map.Set(index, true);
                    items.Add(streamMetadata.StreamId, index);
                }

                index++;
            }
        }
        // Reloads segments from storage
        internal void ReloadSegmentsOnRollback(StorageStreamMetadata metadata)
        {
            CheckClosed();
            changeNotified = false;

            // Reaload metadata and segments
            LoadStream(metadata);
        }
        /// <summary>
        /// Constructor that loads the segments from master stream
        /// </summary>
        internal StorageStream(StorageStreamMetadata metadata, Storage _storage)
        {
            if (_storage == null)
            {
                throw new ArgumentNullException("_storage");
            }

            this._storage = _storage;

            LoadStream(metadata);
        }
Esempio n. 6
0
        /// <summary>
        /// Returns table entries
        /// </summary>
        public IEnumerable <StorageStreamMetadata> Get()
        {
            StorageStreamMetadata streamMetadata;

            foreach (StorageStreamMetadata entry in entriesAddedInTransaction.Values)
            {
                yield return(entry);
            }
            for (int i = 0; i < stream.Length / StorageStreamMetadata.StructureSize; i++)
            {
                streamMetadata = StorageStreamMetadata.Load(stream, i);
                if (streamMetadata.StreamId != Guid.Empty)
                {
                    yield return(streamMetadata);
                }
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Gets first segment location for specified streamId or nulll if not found.
        /// </summary>
        public StorageStreamMetadata Get(Guid streamId)
        {
            StorageStreamMetadata result = null;

            int index;

            // Search through entries in memory
            if (!entriesAddedInTransaction.TryGetValue(streamId, out result))
            {
                // Load it from stream table stream
                if (items.TryGetValue(streamId, out index))
                {
                    result = StorageStreamMetadata.Load(stream, index);
                }
            }

            return(result);
        }
Esempio n. 8
0
        /// <summary>
        /// Adds new entry
        /// </summary>
        public StorageStreamMetadata Add(Guid streamId, int tag = 0)
        {
            // Get the position of first empty entry
            int  index          = map.FindFirstEmptyEntry();
            long streamPosition = index * StorageStreamMetadata.StructureSize;

            // Resize stream is needed
            if ((streamPosition + StorageStreamMetadata.StructureSize) > stream.Length)
            {
                int count = (int)stream.Length / StorageStreamMetadata.StructureSize;
                count += Math.Min(Math.Max((int)(count * 1.5), 512), 50000);

                long oldLength = stream.Length;
                stream.SetLength(count * StorageStreamMetadata.StructureSize);

                // Write zeros to newly allocated space
                long bytesToWrite = stream.Length - oldLength;
                stream.Position = oldLength;
                while (bytesToWrite > 0)
                {
                    int amount = (int)Math.Min(bytesToWrite, Tools.EmptyBuffer.Length);
                    stream.Write(Tools.EmptyBuffer, 0, amount);
                    bytesToWrite -= amount;
                }

                stream.Save();
            }

            StorageStreamMetadata streamMetadata = new StorageStreamMetadata(stream)
            {
                FirstSegmentPosition = null,
                StreamId             = streamId,
                Tag = tag,
                StreamTableIndex = index
            };

            entriesAddedInTransaction.Add(streamId, streamMetadata);
            //streamMetadata.Save();

            map.Set(index, true);
            items.Add(streamId, index);

            return(streamMetadata);
        }