/// <summary> /// Gets the data index for record. /// Returns null when at the end of the data index file. /// </summary> /// <returns>The index for record.</returns> /// <param name="recdordNumber">Record number.</param> public BlobIndex GetBlobIndex(long dataIndexNumber) { long positionOfIndex = (dataIndexNumber - 1) * 32; _binaryReader.BaseStream.Position = positionOfIndex; if (this.FileSize > positionOfIndex) { byte[] dataIndexBytes = _binaryReader.ReadBytes(32); var dataIndex = BlobIndex.Parse(dataIndexBytes); if (dataIndex.DocumentKey > 0) { dataIndex.Position = positionOfIndex; return(dataIndex); } } return(null); }
/// <summary> /// Gets the first available data index with space greater than the size specified in bytes. /// The index returned is the size greater than the length with the combined record length and padding bytes. /// </summary> /// <returns>The data index with space greater than length specified.</returns> /// <param name="dataLength">Data length in bytes.</param> public BlobIndex GetBlobIndexWithEnoughSpace(long dataLength) { long positionOfIndex = 0; _binaryReader.BaseStream.Position = positionOfIndex; // search the index cache before going to disk. foreach (var dataIndex in _cache) { if (dataIndex.RecordLength + dataIndex.PaddingLength > dataLength && dataIndex.DocumentKey != 0) { return(dataIndex); } } // position of where to continue the search from on disk. if (_cache.Count() > 0) { positionOfIndex = (_cache.Count() - 1) * 32; } // loop through the index until search key is found. _binaryReader.BaseStream.Position = positionOfIndex; while (_binaryReader.BaseStream.Position < this.FileSize) { // load the bytes, convert to index object and return byte[] dataIndexBytes = _binaryReader.ReadBytes(32); var dataIndex = BlobIndex.Parse(dataIndexBytes); // add the index to the read cache so next search is quicker. _cache.Add(dataIndex); // return the index if there is more space than specified. if (dataIndex.RecordLength + dataIndex.PaddingLength >= dataLength && dataIndex.DocumentKey != 0) { return(dataIndex); } } return(null); }
/// <summary> /// Adds an index to the Data Index file. /// Overwrites the first data index found with a 0 for its document key. /// </summary> public void AddIndexOverwriteDeleted(BlobIndex dataIndex) { // add the index to the dataindex file. _binaryReader.BaseStream.Position = 0; while (_binaryReader.BaseStream.Position < this.FileSize) { // load the bytes, convert to index object and return byte[] dataIndexBytes = _binaryReader.ReadBytes(32); var existingBlobIndex = BlobIndex.Parse(dataIndexBytes); // check if null if (existingBlobIndex.DocumentKey == 0) { _binaryWriter.BaseStream.Position = _binaryReader.BaseStream.Position; _binaryWriter.Write(dataIndex.GetBytes()); _binaryWriter.Flush(); return; } } // not found so add to end. AddIndex(dataIndex); }
/// <summary> /// Finds the Data Index in the file with the given Search Key (Primary Key). /// </summary> /// <returns>The Data Index containing the data record info.</returns> /// <param name="searchKey">The Document Key (Primary Key) of the entity to find.</param> public BlobIndex FindIndex(long documentKey) { if (documentKey == 0) { return(null); } // attempt to find the key by calculation first (Only for Autoincremented document collections). // if cant find then search the full index file. long positionOfIndex = (documentKey - 1) * 32; _binaryReader.BaseStream.Position = positionOfIndex; // dont attempt to load bytes when the document key is at the end of the file if (this.FileSize > positionOfIndex) { byte[] dataIndexBytes = _binaryReader.ReadBytes(32); var dataIndexInitial = BlobIndex.Parse(dataIndexBytes); if (dataIndexInitial.DocumentKey == documentKey) { dataIndexInitial.Position = positionOfIndex; return(dataIndexInitial); } } // search the index cache before going to disk. var fromCache = _cache.SingleOrDefault(key => key.DocumentKey == documentKey && key.DocumentKey > 0); if (fromCache != null) { return(fromCache); } // position of where to continue the search from on disk. if (_cache.Count() > 0) { positionOfIndex = (_cache.Count() - 1) * 32; } else { positionOfIndex = 0; } // loop through the index until search key is found. _binaryReader.BaseStream.Position = positionOfIndex; while (_binaryReader.BaseStream.Position < this.FileSize) { // load the bytes, convert to index object and return byte[] dataIndexBytes = _binaryReader.ReadBytes(32); var dataIndex = BlobIndex.Parse(dataIndexBytes); // add the index to the read cache so next search is quicker. _cache.Add(dataIndex); // if the document key matches return it. if (dataIndex.DocumentKey == documentKey) { dataIndex.Position = positionOfIndex; return(dataIndex); } } // the data index was not found in the data index file. return(null); }