Esempio n. 1
0
        public AllocationTableStruct GetIndexStruct(Int64 currentOffset, StreamStateBehaviour indexStreamStateBehaviour)
        {
            if (indexStreamStateBehaviour != StreamStateBehaviour.UseExistingStream)
            {
                throw new NotSupportedException("Only useexistingstream is currently supported ");
            }

            var result = new AllocationTableStruct
                {
                    Pointers = new Int64[256]
                };

            IndexStream.Seek(currentOffset, SeekOrigin.Begin);

            //
            // the stream is intentionaly left open
            //
            var binaryReader = new BinaryReader(IndexStream);
            for (int elementIndex = 0; elementIndex < 256; elementIndex++)
            {
                result.Pointers[elementIndex] = binaryReader.ReadInt64();
            }

            return result;
        }
Esempio n. 2
0
        private Int64 GetOffsetInCurrentStream(Guid dataIdentifier, int currentIndexInGuid, Int64 currentOffset)
        {
            Int64 result;

            byte[] bytes = dataIdentifier.ToByteArray();
            int indexerInGuid = bytes[currentIndexInGuid];

            var currentIndexStruct = new AllocationTableStruct
                {
                    Pointers = new Int64[256]
                };

            IndexStream.Seek(currentOffset, SeekOrigin.Begin);

            var binaryReader = new BinaryReader(IndexStream);

            for (int elementIndex = 0; elementIndex < 256; elementIndex++)
            {
                currentIndexStruct.Pointers[elementIndex] = binaryReader.ReadInt64();
            }

            if (currentIndexInGuid < 15)
            {
                long nextOffset = currentIndexStruct.Pointers[indexerInGuid];

                if (nextOffset == 0)
                {
                    //
                    // file does not exist
                    //
                    result = 0;
                }
                else
                {
                    //
                    // recursively call BuildIndex for the next index in the guid
                    //
                    result = GetOffsetInCurrentStream(dataIdentifier, currentIndexInGuid + 1, nextOffset);
                }
            }
            else if (currentIndexInGuid == 15)
            {
                //
                // we reached the last index struct
                //

                if (currentIndexStruct.Pointers[indexerInGuid] == 0)
                {
                    //
                    // file does not exist
                    //
                    result = 0;
                }
                else
                {
                    result = currentIndexStruct.Pointers[indexerInGuid];
                }
            }
            else
            {
                throw new IndexOutOfRangeException(currentIndexInGuid.ToString());
            }

            return result;
        }
Esempio n. 3
0
        private void BuildIndex(Guid dataIdentifier, int currentIndexInGuid, Int64 currentOffset, Int64 dataOffset, BuildIndexBehaviour buildIndexBehaviour, StreamStateBehaviour indexStreamStateBehaviour)
        {
            byte[] bytes = dataIdentifier.ToByteArray();
            int indexerInGuid = bytes[currentIndexInGuid];
            Int64 endOfFileOffset = IndexStream.Length;

            AllocationTableStruct currentIndexStruct = GetIndexStruct(currentOffset, indexStreamStateBehaviour);

            if (currentIndexInGuid < 15)
            {
                long nextOffset = currentIndexStruct.Pointers[indexerInGuid];

                if (nextOffset == 0)
                {
                    //
                    // does not point to anywhere; this means we have to;
                    // * append a new block at the end of the file, with 0-pointers for each guid indexer over there
                    // * update the reference for the specific index in the guid to the end of the filestream
                    //

                    // update the struct
                    currentIndexStruct.Pointers[indexerInGuid] = endOfFileOffset;
                    // write the struct
                    StoreStruct(currentOffset, currentIndexStruct);

                    // create a new struct with offsets 0 for each index in guid
                    var newIndexStruct = new AllocationTableStruct
                        {
                            Pointers = new Int64[256]
                        };

                    StoreStruct(endOfFileOffset, newIndexStruct);

                    nextOffset = endOfFileOffset;

                    //
                    // recursively call BuildIndex for the next index in the guid
                    //
                    BuildIndex(dataIdentifier, currentIndexInGuid + 1, nextOffset, dataOffset, buildIndexBehaviour, indexStreamStateBehaviour);
                }
                else
                {
                    //
                    // recursively call BuildIndex for the next index in the guid
                    //
                    BuildIndex(dataIdentifier, currentIndexInGuid + 1, nextOffset, dataOffset, buildIndexBehaviour, indexStreamStateBehaviour);
                }
            }
            else if (currentIndexInGuid == 15)
            {
                //
                // we reached the last index struct
                //

                switch (buildIndexBehaviour)
                {
                    case BuildIndexBehaviour.OverrideWhenAlreadyExists:
                        //
                        // no matter if it already existed or not, we will override it
                        //
                        break;
                    case BuildIndexBehaviour.ThrowExceptionWhenIndexAlreadyExists:
                        if (currentIndexStruct.Pointers[indexerInGuid] == 0)
                        {
                            //
                            // its still free, continue
                            //
                            break;
                        }

                        //
                        // if we reach this point, it means the pointer was already allocated
                        //
                        throw new NotSupportedException(string.Format("Index {0} is already allocated", dataIdentifier));
                    default:
                        throw new NotSupportedException(string.Format("{0} is an unsupported BuildIndexBehaviour", buildIndexBehaviour));
                }

                currentIndexStruct.Pointers[indexerInGuid] = dataOffset;
                // store the index block
                StoreStruct(currentOffset, currentIndexStruct);
            }
            else
            {
                throw new IndexOutOfRangeException(currentIndexInGuid.ToString());
            }
        }
Esempio n. 4
0
 private void StoreStruct(Int64 offsetInFileFromBegin, AllocationTableStruct indexStruct)
 {
     //
     // re-open the file to allow accessing the newly added bytes
     // 
     // point to the end of the file
     IndexStream.Seek(offsetInFileFromBegin, SeekOrigin.Begin);
     // write the struct
     var binaryWriter = new BinaryWriter(IndexStream);
     foreach (Int64 c in indexStruct.Pointers)
     {
         binaryWriter.Write(c);
     }
 }
Esempio n. 5
0
        private static void CreateNewFileStorage_IndexFile(string indexFilename)
        {
            using (FileStream indexStream = File.Create(indexFilename))
            {
                #region store the header

                var indexFileHeaderStruct = new IndexFileHeaderStruct
                    {
                        VersionMajor = VersionMajor,
                        VersionMinor = VersionMinor
                    };

                string template = "[IndexFile of FileStorage. Check out www.constantum.com]";
                template = template.PadRight(92, '-');
                indexFileHeaderStruct.Text = template.ToCharArray();

                #region store header

                // point to the beginning of the file
                indexStream.Seek(0, SeekOrigin.Begin);
                // write the struct

                //
                // the stream is intentionally left open
                //
                var binaryWriter = new BinaryWriter(indexStream);
                binaryWriter.Write(indexFileHeaderStruct.VersionMajor);
                binaryWriter.Write(indexFileHeaderStruct.VersionMinor);
                binaryWriter.Write(indexFileHeaderStruct.Text);

                #endregion

                #endregion

                #region store the initial index table

                const long offset = OffsetFirstIndexBlock;

                // create a new struct with offsets 0 for each index in guid
                var newIndexStruct = new AllocationTableStruct
                    {
                        Pointers = new Int64[256]
                    };

                //
                // re-open the file to allow accessing the newly added bytes
                // 
                // point to the end of the file
                indexStream.Seek(offset, SeekOrigin.Begin);
                // write the struct
                foreach (Int64 c in newIndexStruct.Pointers)
                {
                    binaryWriter.Write(c);
                }

                #endregion
            }
        }