Example #1
0
        public SnapshotIndexSet(IndexSetStore indexSetStore, IndexBlock[] blocks)
        {
            this.indexSetStore = indexSetStore;
            IndexBlocks = blocks;

            // Not disposed.
            disposed = false;
        }
        public void Open(long startPointer)
        {
            lock (this) {
                // Set up the start area
                startArea = Store.GetArea(startPointer);

                int magic = startArea.ReadInt4();
                if (magic != Magic)
                {
                    throw new IOException("Magic value for index set does not match.");
                }

                int version = startArea.ReadInt4();
                if (version != 1)
                {
                    throw new IOException("Unknown version for index set.");
                }

                // Setup the index_header area
                indexHeaderPointer = startArea.ReadInt8();
                indexHeaderArea    = Store.GetArea(indexHeaderPointer);

                // Read the index header area
                version = indexHeaderArea.ReadInt4();                 // version
                if (version != 1)
                {
                    throw new IOException("Incorrect version");
                }

                indexHeaderArea.ReadInt4();                 // reserved
                int indexCount = (int)indexHeaderArea.ReadInt8();
                indexBlocks = new IndexBlock[indexCount];

                // Initialize each index block
                for (int i = 0; i < indexCount; ++i)
                {
                    int  type              = indexHeaderArea.ReadInt4();
                    int  blockSize         = indexHeaderArea.ReadInt4();
                    long indexBlockPointer = indexHeaderArea.ReadInt8();
                    if (type != 1)
                    {
                        throw new IOException("Do not understand index type: " + type);
                    }

                    indexBlocks[i] = new IndexBlock(this, i, blockSize, indexBlockPointer);
                    indexBlocks[i].AddReference();
                }
            }
        }
        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();
                }
            }
        }
Example #4
0
        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();
                }
            }
        }
Example #5
0
        public void PrepareIndexLists(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.ReadInt4();
                        int reserved = indexHeaderArea.ReadInt4();
                        long icount = indexHeaderArea.ReadInt8();
                        newIndexArea.WriteInt4(version);
                        newIndexArea.WriteInt4(reserved);
                        newIndexArea.WriteInt8(icount + count);

                        for (int i = 0; i < indexBlocks.Length; ++i) {
                            int itype = indexHeaderArea.ReadInt4();
                            int iblockSize = indexHeaderArea.ReadInt4();
                            long indexBlockP = indexHeaderArea.ReadInt8();

                            newIndexArea.WriteInt4(itype);
                            newIndexArea.WriteInt4(iblockSize);
                            newIndexArea.WriteInt8(indexBlockP);

                            newIndexBlocks[i] = indexBlocks[i];
                        }

                        // Add the new entries
                        for (int i = 0; i < count; ++i) {
                            long newBlankBlockP = CreateNewBlock();

                            newIndexArea.WriteInt4(type);
                            newIndexArea.WriteInt4(blockSize);
                            newIndexArea.WriteInt8(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.WriteInt8(newIndexPointer);
                        startArea.Flush();

                        // Free the old header
                        Store.DeleteArea(oldIndexHeaderP);
                    }
                } finally {
                    Store.Unlock();
                }
            }
        }
Example #6
0
        public void Open(long startPointer)
        {
            lock (this) {
                // Set up the start area
                startArea = Store.GetArea(startPointer);

                int magic = startArea.ReadInt4();
                if (magic != Magic)
                    throw new IOException("Magic value for index set does not match.");

                int version = startArea.ReadInt4();
                if (version != 1)
                    throw new IOException("Unknown version for index set.");

                // Setup the index_header area
                indexHeaderPointer = startArea.ReadInt8();
                indexHeaderArea = Store.GetArea(indexHeaderPointer);

                // Read the index header area
                version = indexHeaderArea.ReadInt4(); // version
                if (version != 1)
                    throw new IOException("Incorrect version");

                indexHeaderArea.ReadInt4(); // reserved
                int indexCount = (int)indexHeaderArea.ReadInt8();
                indexBlocks = new IndexBlock[indexCount];

                // Initialize each index block
                for (int i = 0; i < indexCount; ++i) {
                    int type = indexHeaderArea.ReadInt4();
                    int blockSize = indexHeaderArea.ReadInt4();
                    long indexBlockPointer = indexHeaderArea.ReadInt8();
                    if (type != 1)
                        throw new IOException("Do not understand index type: " + type);

                    indexBlocks[i] = new IndexBlock(this, i, blockSize, indexBlockPointer);
                    indexBlocks[i].AddReference();
                }
            }
        }
Example #7
0
        public void CommitIndexSet(IIndexSet indexSet)
        {
            var removedBlocks = new List<IndexBlock>();

            lock (this) {
                var sIndexSet = (SnapshotIndexSet)indexSet;
                var indices = sIndexSet.AllIndices.ToList();

                try {
                    try {
                        Store.Lock();

                        // For each Index in the index set,
                        foreach (var index in indices) {
                            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.WriteInt4(1); // version
                                area.WriteInt4(0); // reserved
                                area.WriteInt8(blocks.Count); // block count

                                foreach (var block in blocks) {
                                    var mappedBlock = (IMappedBlock) block;

                                    long bottomInt = 0;
                                    long topInt = 0;
                                    int 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.WriteInt8(bottomInt);
                                    area.WriteInt8(topInt);
                                    area.WriteInt8(blockPointer);
                                    area.WriteInt4(blockSize | (((int) 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();
            }
        }
        public void CommitIndexSet(IIndexSet indexSet)
        {
            var removedBlocks = new List <IndexBlock>();

            lock (this) {
                var sIndexSet = (SnapshotIndexSet)indexSet;
                var indices   = sIndexSet.AllIndices.ToList();

                try {
                    try {
                        Store.Lock();

                        // For each Index in the index set,
                        foreach (var index in indices)
                        {
                            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.WriteInt4(1);                                 // version
                                area.WriteInt4(0);                                 // reserved
                                area.WriteInt8(blocks.Count);                      // block count

                                foreach (var block in blocks)
                                {
                                    var mappedBlock = (IMappedBlock)block;

                                    long bottomInt = 0;
                                    long topInt    = 0;
                                    int  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.WriteInt8(bottomInt);
                                    area.WriteInt8(topInt);
                                    area.WriteInt8(blockPointer);
                                    area.WriteInt4(blockSize | (((int)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();
            }
        }
        public void PrepareIndexLists(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.ReadInt4();
                        int  reserved = indexHeaderArea.ReadInt4();
                        long icount   = indexHeaderArea.ReadInt8();
                        newIndexArea.WriteInt4(version);
                        newIndexArea.WriteInt4(reserved);
                        newIndexArea.WriteInt8(icount + count);

                        for (int i = 0; i < indexBlocks.Length; ++i)
                        {
                            int  itype       = indexHeaderArea.ReadInt4();
                            int  iblockSize  = indexHeaderArea.ReadInt4();
                            long indexBlockP = indexHeaderArea.ReadInt8();

                            newIndexArea.WriteInt4(itype);
                            newIndexArea.WriteInt4(iblockSize);
                            newIndexArea.WriteInt8(indexBlockP);

                            newIndexBlocks[i] = indexBlocks[i];
                        }

                        // Add the new entries
                        for (int i = 0; i < count; ++i)
                        {
                            long newBlankBlockP = CreateNewBlock();

                            newIndexArea.WriteInt4(type);
                            newIndexArea.WriteInt4(blockSize);
                            newIndexArea.WriteInt8(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.WriteInt8(newIndexPointer);
                        startArea.Flush();

                        // Free the old header
                        Store.DeleteArea(oldIndexHeaderP);
                    }
                } finally {
                    Store.Unlock();
                }
            }
        }