18 using System.Collections.Generic;
26 namespace Deveel.Data.Index {
37 private const int Magic = 0x0CA90291;
43 public IStore Store {
get;
private set; }
51 foreach (var
id in deletedAreas) {
55 }
catch (IOException) {
66 var a = Store.CreateArea(16);
67 long indexBlockP = a.Id;
80 var a = Store.CreateArea(16);
81 indexHeaderPointer = a.Id;
88 indexHeaderArea = Store.GetArea(indexHeaderPointer);
93 var sa = Store.CreateArea(32);
94 long startPointer = sa.Id;
100 sa.WriteInt8(indexHeaderPointer);
104 startArea = Store.GetArea(startPointer);
110 public void Open(
long startPointer) {
113 startArea = Store.GetArea(startPointer);
115 int magic = startArea.ReadInt4();
117 throw new IOException(
"Magic value for index set does not match.");
119 int version = startArea.ReadInt4();
121 throw new IOException(
"Unknown version for index set.");
124 indexHeaderPointer = startArea.ReadInt8();
125 indexHeaderArea = Store.GetArea(indexHeaderPointer);
128 version = indexHeaderArea.ReadInt4();
130 throw new IOException(
"Incorrect version");
132 indexHeaderArea.ReadInt4();
133 int indexCount = (int)indexHeaderArea.ReadInt8();
137 for (
int i = 0; i < indexCount; ++i) {
138 int type = indexHeaderArea.ReadInt4();
139 int blockSize = indexHeaderArea.ReadInt4();
140 long indexBlockPointer = indexHeaderArea.ReadInt8();
142 throw new IOException(
"Do not understand index type: " + type);
144 indexBlocks[i] =
new IndexBlock(
this, i, blockSize, indexBlockPointer);
153 for (
int i = 0; i < indexBlocks.Length; ++i) {
163 list.Add(startArea.
Id);
164 list.Add(indexHeaderPointer);
166 foreach (var block
in indexBlocks) {
167 list.Add(block.StartOffset);
168 long[] blockPointers = block.GetBlockPointers();
169 list.AddRange(blockPointers);
179 int newSize = 16 + ((indexBlocks.Length + count) * 16);
180 var newIndexArea = Store.CreateArea(newSize);
181 long newIndexPointer = newIndexArea.Id;
182 var newIndexBlocks =
new IndexBlock[(indexBlocks.Length + count)];
186 int version = indexHeaderArea.ReadInt4();
187 int reserved = indexHeaderArea.ReadInt4();
188 long icount = indexHeaderArea.ReadInt8();
189 newIndexArea.WriteInt4(version);
190 newIndexArea.WriteInt4(reserved);
191 newIndexArea.WriteInt8(icount + count);
193 for (
int i = 0; i < indexBlocks.Length; ++i) {
194 int itype = indexHeaderArea.ReadInt4();
195 int iblockSize = indexHeaderArea.ReadInt4();
196 long indexBlockP = indexHeaderArea.ReadInt8();
198 newIndexArea.WriteInt4(itype);
199 newIndexArea.WriteInt4(iblockSize);
200 newIndexArea.WriteInt8(indexBlockP);
202 newIndexBlocks[i] = indexBlocks[i];
206 for (
int i = 0; i < count; ++i) {
207 long newBlankBlockP = CreateNewBlock();
209 newIndexArea.WriteInt4(type);
210 newIndexArea.WriteInt4(blockSize);
211 newIndexArea.WriteInt8(newBlankBlockP);
213 var newBlock =
new IndexBlock(
this, indexBlocks.Length + i, blockSize, newBlankBlockP);
214 newBlock.AddReference();
215 newIndexBlocks[indexBlocks.Length + i] = newBlock;
219 newIndexArea.Flush();
222 long oldIndexHeaderP = indexHeaderPointer;
225 indexHeaderPointer = newIndexPointer;
226 indexHeaderArea = Store.GetArea(newIndexPointer);
227 indexBlocks = newIndexBlocks;
231 startArea.WriteInt8(newIndexPointer);
235 Store.DeleteArea(oldIndexHeaderP);
246 var snapshotIndexBlocks = (
IndexBlock[])indexBlocks.Clone();
249 for (
int i = 0; i < snapshotIndexBlocks.Length; ++i) {
260 var a = Store.CreateArea(16 + (indexBlocks.Length * 16));
265 a.WriteInt8(indexBlocks.Length);
267 foreach (var indBlock
in indexBlocks) {
269 a.WriteInt4(indBlock.BlockSize);
270 a.WriteInt8(indBlock.StartOffset);
277 long oldIndexHeaderP = indexHeaderPointer;
280 indexHeaderPointer = aOffset;
281 indexHeaderArea = Store.GetArea(indexHeaderPointer);
285 startArea.WriteInt8(indexHeaderPointer);
289 Store.DeleteArea(oldIndexHeaderP);
294 var removedBlocks =
new List<IndexBlock>();
298 var indices = sIndexSet.AllIndices.ToList();
305 foreach (var index
in indices) {
306 int indexNum = index.IndexNumber;
309 var curIndexBlock = indexBlocks[indexNum];
312 var blocks = index.AllBlocks.ToList();
315 var area = Store.CreateArea(16 + (blocks.Count * 28));
316 long blockP = area.Id;
319 area.WriteInt8(blocks.Count);
321 foreach (var block
in blocks) {
326 int blockSize = mappedBlock.Count;
328 bottomInt = mappedBlock.Bottom;
329 topInt = mappedBlock.Top;
332 long blockPointer = mappedBlock.BlockPointer;
335 if (blockPointer == -1 || mappedBlock.HasChanged) {
338 if (blockPointer != -1)
343 blockPointer = mappedBlock.Flush();
346 area.WriteInt8(bottomInt);
347 area.WriteInt8(topInt);
348 area.WriteInt8(blockPointer);
349 area.WriteInt4(blockSize | (((
int)mappedBlock.CompactType) << 24));
356 var deletedBlocks = index.DeletedBlocks.ToArray();
357 for (
int i = 0; i < deletedBlocks.Length; ++i) {
358 long delBlockP = deletedBlocks[i].BlockPointer;
360 curIndexBlock.AddDeletedArea(delBlockP);
364 curIndexBlock.MarkAsDeleted();
367 var newIndexBlock =
new IndexBlock(
this, indexNum, curIndexBlock.BlockSize, blockP);
368 newIndexBlock.Parent = curIndexBlock;
371 newIndexBlock.AddReference();
374 indexBlocks[indexNum] = newIndexBlock;
377 removedBlocks.Add(curIndexBlock);
388 }
catch (IOException e) {
389 throw new InvalidOperationException(
"Error while committing index changed", e);
395 foreach (var block
in removedBlocks) {
396 block.RemoveReference();
403 var curIndexBlock = indexBlocks[indexNum];
410 var allBlockPointers = curIndexBlock.GetBlockPointers();
411 foreach (
long area
in allBlockPointers) {
412 curIndexBlock.AddDeletedArea(area);
416 curIndexBlock.MarkAsDeleted();
419 long blockP = CreateNewBlock();
422 var newIndexBlock =
new IndexBlock(
this, indexNum, blockSize, blockP);
425 newIndexBlock.AddReference();
427 curIndexBlock.RemoveReference();
429 indexBlocks[indexNum] = newIndexBlock;
The context of a single database within a system.
void CommitDropIndex(int indexNum)
void PrepareIndexLists(int count, int type, int blockSize)
long Position
Returns or sets the current position of the pointer within the area.
void Open(long startPointer)
void GetAreasUsed(List< long > list)
IIndexSet GetSnapshotIndex()
void DeleteAreas(IEnumerable< int > deletedAreas)
An interface for access the contents of an area of a store.
An object that access to a set of indexes.
void AddDeletedArea(long pointer)
IndexSetStore(IDatabaseContext databaseContext, IStore store)
long Id
Returns the unique identifier that represents this area.
void CommitIndexSet(IIndexSet indexSet)
A store is a resource where areas can be allocated and freed to store information (a memory allocator...