public void BuildIndex(Guid dataIdentifier, Int64 dataOffset, BuildIndexBehaviour buildIndexBehaviour, StreamStateBehaviour indexStreamStateBehaviour) { int indexInGuid = 0; long currentOffsetInIndexFile = OffsetFirstIndexBlock; BuildIndex(dataIdentifier, indexInGuid, currentOffsetInIndexFile, dataOffset, buildIndexBehaviour, indexStreamStateBehaviour); }
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()); } }