public void CommitDropIndex(int indexNum) { lock (this) { // The IndexBlock we are dropping var curIndexBlock = indexBlocks[indexNum]; int blockSize = curIndexBlock.BlockSize; try { Store.Lock(); // Add all the elements to the deleted areas in the block var allBlockPointers = curIndexBlock.GetBlockPointers(); foreach (long area in allBlockPointers) { curIndexBlock.AddDeletedArea(area); } // Mark the current block as deleted curIndexBlock.MarkAsDeleted(); // Make up a new blank block list for this index set. long blockP = CreateNewBlock(); // Now create a new IndexBlock object var newIndexBlock = new IndexBlock(this, indexNum, blockSize, blockP); // Add reference to the new one newIndexBlock.AddReference(); // Remove reference to the old curIndexBlock.RemoveReference(); // Update the index_blocks list indexBlocks[indexNum] = newIndexBlock; // Commit the new index header (index_blocks) CommitIndexHeader(); } finally { Store.Unlock(); } } }
public void CommitIndexSet(IRowIndexSet indexSet) { var removedBlocks = new List <IndexBlock>(); lock (this) { var sIndexSet = (SnapshotIndexSet)indexSet; try { try { Store.Lock(); // For each Index in the index set, foreach (Index index in sIndexSet) { int indexNum = index.IndexNumber; // The IndexBlock we are changing var curIndexBlock = indexBlocks[indexNum]; // Get all the blocks in the list var blocks = index.AllBlocks.ToList(); // Make up a new block list for this index set. long blockP; using (var area = Store.CreateArea(16 + (blocks.Count * 28))) { blockP = area.Id; area.Write(1); // version area.Write(0); // reserved area.Write((long)blocks.Count); // block count foreach (var block in blocks) { var mappedBlock = (IMappedBlock)block; long bottomInt = 0; long topInt = 0; var blockSize = mappedBlock.Count; if (blockSize > 0) { bottomInt = mappedBlock.Bottom; topInt = mappedBlock.Top; } long blockPointer = mappedBlock.BlockPointer; // Is the block new or was it changed? if (blockPointer == -1 || mappedBlock.HasChanged) { // If this isn't -1 then write this sector on the list of // sectors to delete during GC. if (blockPointer != -1) { curIndexBlock.AddDeletedArea(blockPointer); } // This is a new block or a block that's been changed // Write the block to the file system blockPointer = mappedBlock.Flush(); } area.Write(bottomInt); area.Write(topInt); area.Write(blockPointer); area.Write((int)(blockSize | ((mappedBlock.CompactType) << 24))); } // Finish initializing the area area.Flush(); } // Add the deleted blocks var deletedBlocks = index.DeletedBlocks.ToArray(); for (int i = 0; i < deletedBlocks.Length; ++i) { long delBlockP = deletedBlocks[i].BlockPointer; if (delBlockP != -1) { curIndexBlock.AddDeletedArea(delBlockP); } } // Mark the current block as deleted curIndexBlock.MarkAsDeleted(); // Now create a new IndexBlock object var newIndexBlock = new IndexBlock(this, indexNum, curIndexBlock.BlockSize, blockP); newIndexBlock.Parent = curIndexBlock; // Add reference to the new one newIndexBlock.AddReference(); // Update the index_blocks list indexBlocks[indexNum] = newIndexBlock; // We remove this later. removedBlocks.Add(curIndexBlock); } // Commit the new index header (index_blocks) CommitIndexHeader(); } finally { Store.Unlock(); } // Commit finished. } catch (IOException e) { throw new InvalidOperationException("Error while committing index changed", e); } } // Remove all the references for the changed blocks, foreach (var block in removedBlocks) { block.RemoveReference(); } }
internal void PrepareIndexes(int count, int type, int blockSize) { lock (this) { try { Store.Lock(); // Allocate a new area for the list int newSize = 16 + ((indexBlocks.Length + count) * 16); using (var newIndexArea = Store.CreateArea(newSize)) { long newIndexPointer = newIndexArea.Id; var newIndexBlocks = new IndexBlock[(indexBlocks.Length + count)]; // Copy the existing area indexHeaderArea.Position = 0; int version = indexHeaderArea.ReadInt32(); int reserved = indexHeaderArea.ReadInt32(); long icount = indexHeaderArea.ReadInt64(); newIndexArea.Write(version); newIndexArea.Write(reserved); newIndexArea.Write(icount + count); for (int i = 0; i < indexBlocks.Length; ++i) { int itype = indexHeaderArea.ReadInt32(); int iblockSize = indexHeaderArea.ReadInt32(); long indexBlockP = indexHeaderArea.ReadInt64(); newIndexArea.Write(itype); newIndexArea.Write(iblockSize); newIndexArea.Write(indexBlockP); newIndexBlocks[i] = indexBlocks[i]; } // Add the new entries for (int i = 0; i < count; ++i) { long newBlankBlockP = CreateNewBlock(); newIndexArea.Write(type); newIndexArea.Write(blockSize); newIndexArea.Write(newBlankBlockP); var newBlock = new IndexBlock(this, indexBlocks.Length + i, blockSize, newBlankBlockP); newBlock.AddReference(); newIndexBlocks[indexBlocks.Length + i] = newBlock; } // Finished initializing the index. newIndexArea.Flush(); // The old index header pointer long oldIndexHeaderP = indexHeaderPointer; // Update the state of this object, indexHeaderPointer = newIndexPointer; indexHeaderArea = Store.GetArea(newIndexPointer); indexBlocks = newIndexBlocks; // Update the start pointer startArea.Position = 8; startArea.Write(newIndexPointer); startArea.Flush(); // Free the old header Store.DeleteArea(oldIndexHeaderP); } } finally { Store.Unlock(); } } }