DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
Classes | Public Member Functions | Protected Member Functions | Package Functions | Properties | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | List of all members
Deveel.Data.Store.StoreBase Class Referenceabstract
Inheritance diagram for Deveel.Data.Store.StoreBase:
Deveel.Data.Store.IStore Deveel.Data.Store.SingleFileStore

Classes

class  StoreArea
 An IArea that is backed by a StoreBase. More...
 

Public Member Functions

bool Open ()
 
void Close ()
 
void Dispose ()
 
IArea CreateArea (long size)
 Allocates a block of memory in the store of the specified size and returns an IArea object that can be used to initialize the contents of the area. More...
 
void DeleteArea (long id)
 Deletes an area that was previously allocated by the CreateArea method by the area id. More...
 
IArea GetArea (long id, bool readOnly)
 Returns an object that allows for the contents of an area (represented by the id parameter) to be Read. More...
 
abstract void Lock ()
 This method is called before the start of a sequence of Write commands between consistant states of some data structure represented by the store. More...
 
abstract void Unlock ()
 This method is called after the end of a sequence of Write commands between consistant states of some data structure represented by the store. More...
 
IEnumerable< long > GetAllAreas ()
 Returns a complete list of pointers to all areas in the Store as long objects sorted from lowest pointer to highest. More...
 

Protected Member Functions

 StoreBase (bool isReadOnly)
 
void ReadAreaHeader (long offset, long[] header)
 
void SplitArea (long offset, long newBoundary)
 
abstract void SetDataAreaSize (long length)
 
virtual void Dispose (bool disposing)
 
abstract void OpenStore (bool readOnly)
 
abstract void CloseStore ()
 
int ReadByte (long offset)
 
abstract int Read (long offset, byte[] buffer, int index, int length)
 
void Write (long offset, byte value)
 
abstract void Write (long offset, byte[] buffer, int index, int length)
 

Package Functions

IEnumerable< long > FindAllocatedAreasNotIn (List< long > usedAreas)
 

Properties

long WildernessOffset [get, set]
 
bool IsReadOnly [get, private set]
 
abstract long DataAreaEndOffset [get]
 
bool ClosedClean [get, private set]
 
- Properties inherited from Deveel.Data.Store.IStore
bool ClosedClean [get]
 Indicates if the store was closed cleanly last time was accessed. More...
 

Private Member Functions

 ~StoreBase ()
 
void CheckOffset (long offset)
 
void ReadBins ()
 
void WriteAllBins ()
 
void WriteBinIndex (int index)
 
void AddToBinChain (long pointer, long size)
 
void RemoveFromBinChain (long offset, long size)
 
void Free (long pointer)
 
long GetPreviousAreaHeader (long offset, long[] header)
 
long GetNextAreaHeader (long offset, long[] header)
 
void ReboundArea (long offset, long[] header, bool writeHeaders)
 
void CoalesceArea (long offset, long size)
 
void CropArea (long offset, long allocatedSize)
 
long Alloc (long size)
 
long ExpandDataArea (long minSize)
 
void Init ()
 

Static Private Member Functions

static int MinimumBinSizeIndex (long size)
 
static bool IsValidBoundarySize (long size)
 

Private Attributes

long[] freeBinList
 
long totalAllocatedSpace
 
readonly byte[] binArea = new byte[128 * 8]
 
const long ActiveFlag = Int64.MaxValue
 
const long DeletedFlag = Int64.MinValue
 
const long FixedAreaOffset = 128
 
const long DataAreaOffset = 256 + 1024 + 32
 
const long BinAreaOffset = 256
 
const int Magic = 0x0AEAE91
 
readonly byte[] headerBuf = new byte[16]
 
bool disposed
 

Static Private Attributes

static readonly int[] BinSizes
 
static readonly int BinSizeEntries = BinSizes.Length
 
static readonly int MaxBinSize = BinSizes[BinSizeEntries - 1]
 

Detailed Description

Definition at line 25 of file StoreBase.cs.

Constructor & Destructor Documentation

Deveel.Data.Store.StoreBase.StoreBase ( bool  isReadOnly)
inlineprotected

Definition at line 61 of file StoreBase.cs.

61  {
62  freeBinList = new long[BinSizeEntries + 1];
63  for (int i = 0; i < BinSizeEntries + 1; ++i) {
64  freeBinList[i] = -1L;
65  }
66 
67  WildernessOffset = -1;
68 
69  IsReadOnly = isReadOnly;
70  }
static readonly int BinSizeEntries
Definition: StoreBase.cs:46
Deveel.Data.Store.StoreBase.~StoreBase ( )
inlineprivate

Definition at line 72 of file StoreBase.cs.

72  {
73  Dispose(false);
74  }

Member Function Documentation

void Deveel.Data.Store.StoreBase.AddToBinChain ( long  pointer,
long  size 
)
inlineprivate

Definition at line 125 of file StoreBase.cs.

125  {
126  CheckOffset(pointer);
127 
128  // What bin would this area fit into?
129  int binChainIndex = MinimumBinSizeIndex(size);
130  var headerInfo = new long[2];
131 
132  long curOffset = freeBinList[binChainIndex];
133 
134  if (curOffset == -1) {
135  // If the bin chain has no elements,
136  headerInfo[0] = (size | DeletedFlag);
137  headerInfo[1] = -1;
138 
139  ReboundArea(pointer, headerInfo, true);
140  freeBinList[binChainIndex] = pointer;
141 
142  WriteBinIndex(binChainIndex);
143  } else {
144  bool inserted = false;
145  long lastOffset = -1;
146  int searches = 0;
147  while (curOffset != -1 && inserted == false) {
148  // Get the current offset
149  ReadAreaHeader(curOffset, headerInfo);
150 
151  long header = headerInfo[0];
152  long next = headerInfo[1];
153 
154  // Assert - the header must have deleted flag
155  if ((header & DeletedFlag) == 0)
156  throw new IOException("Area not marked as deleted.");
157 
158  long areaSize = header ^ DeletedFlag;
159  if (areaSize >= size || searches >= 12) {
160  // Insert if the area size is >= than the size we are adding.
161  // Set the previous header to point to this
162  long previous = lastOffset;
163 
164  // Set up the deleted area
165  headerInfo[0] = (size | DeletedFlag);
166  headerInfo[1] = curOffset;
167 
168  ReboundArea(pointer, headerInfo, true);
169 
170  if (lastOffset != -1) {
171  // Set the previous input the chain to point to the deleted area
172  ReadAreaHeader(previous, headerInfo);
173 
174  headerInfo[1] = pointer;
175  ReboundArea(previous, headerInfo, false);
176  } else {
177  // Otherwise set the head bin item
178  freeBinList[binChainIndex] = pointer;
179  WriteBinIndex(binChainIndex);
180  }
181 
182  inserted = true;
183  }
184 
185  lastOffset = curOffset;
186  curOffset = next;
187  ++searches;
188  }
189 
190  // If we reach the end and we haven't inserted,
191  if (!inserted) {
192  // Set the new deleted area.
193  headerInfo[0] = (size | DeletedFlag);
194  headerInfo[1] = -1;
195  ReboundArea(pointer, headerInfo, true);
196 
197  // Set the previous entry to this
198  ReadAreaHeader(lastOffset, headerInfo);
199  headerInfo[1] = pointer;
200  ReboundArea(lastOffset, headerInfo, false);
201  }
202  }
203  }
static int MinimumBinSizeIndex(long size)
Definition: StoreBase.cs:89
void ReboundArea(long offset, long[] header, bool writeHeaders)
Definition: StoreBase.cs:350
void CheckOffset(long offset)
Definition: StoreBase.cs:82
void WriteBinIndex(int index)
Definition: StoreBase.cs:118
void ReadAreaHeader(long offset, long[] header)
Definition: StoreBase.cs:342
long Deveel.Data.Store.StoreBase.Alloc ( long  size)
inlineprivate

Definition at line 408 of file StoreBase.cs.

408  {
409  if (size < 0)
410  throw new IOException("Negative size allocation");
411 
412  // Add 16 bytes for headers
413  size = size + 16;
414 
415  // If size < 32, make size = 32
416  if (size < 32)
417  size = 32;
418 
419  // Round all sizes up to the nearest 8
420  long d = size & 0x07L;
421  if (d != 0)
422  size = size + (8 - d);
423 
424  long realAllocSize = size;
425 
426  // Search the free bin list for the first bin that matches the given size.
427  int binChainIndex;
428  if (size > MaxBinSize) {
429  binChainIndex = BinSizeEntries;
430  } else {
431  int i = MinimumBinSizeIndex(size);
432  binChainIndex = i;
433  }
434 
435  // Search the bins until we find the first area that is the nearest fit to
436  // the size requested.
437  int foundBinIndex = -1;
438  long prevOffset = -1;
439  bool first = true;
440  for (int i = binChainIndex;
441  i < BinSizeEntries + 1 && foundBinIndex == -1;
442  ++i) {
443  long curOffset = freeBinList[i];
444  if (curOffset != -1) {
445  if (!first) {
446  // Pick this..
447  foundBinIndex = i;
448  prevOffset = -1;
449  } else {
450  // Search this bin for the first that's big enough.
451  // We only search the first 12 entries input the bin before giving up.
452 
453  long lastOffset = -1;
454  int searches = 0;
455  while (curOffset != -1 &&
456  foundBinIndex == -1 &&
457  searches < 12) {
458 
459  var headerInfo = new long[2];
460  ReadAreaHeader(curOffset, headerInfo);
461 
462  long areaSize = (headerInfo[0] & ActiveFlag);
463 
464  // Is this area is greater or equal than the required size
465  // and is not the wilderness area, pick it.
466  if (curOffset != WildernessOffset && areaSize >= size) {
467  foundBinIndex = i;
468  prevOffset = lastOffset;
469  }
470 
471  // Go to next input chain.
472  lastOffset = curOffset;
473  curOffset = headerInfo[1];
474  ++searches;
475  }
476  }
477 
478  }
479 
480  first = false;
481  }
482 
483  // If no area can be recycled,
484  if (foundBinIndex == -1) {
485  // Allocate a new area of the given size.
486  // If there is a wilderness, grow the wilderness area to the new size,
487  long workingOffset;
488  long sizeToGrow;
489  long currentAreaSize;
490  if (WildernessOffset != -1) {
491  workingOffset = WildernessOffset;
492 
493  var headerInfo = new long[2];
494  ReadAreaHeader(WildernessOffset, headerInfo);
495 
496  long wildernessSize = (headerInfo[0] & ActiveFlag);
497 
498  // Remove this from the bins
499  RemoveFromBinChain(workingOffset, wildernessSize);
500 
501  // For safety, we set wilderness_pointer to -1
502  WildernessOffset = -1;
503  sizeToGrow = size - wildernessSize;
504  currentAreaSize = wildernessSize;
505  } else {
506  // wilderness_pointer == -1 so add to the end of the data area.
507  workingOffset = DataAreaEndOffset;
508  sizeToGrow = size;
509  currentAreaSize = 0;
510  }
511 
512  long expandedSize = 0;
513  if (sizeToGrow > 0) {
514  // Expand the data area to the new size.
515  expandedSize = ExpandDataArea(sizeToGrow);
516  }
517 
518  // Coalesce the new area to the given size
519  CoalesceArea(workingOffset, currentAreaSize + expandedSize);
520 
521  // crop the area
522  CropArea(workingOffset, size);
523 
524  // Add to the total allocated space
525  totalAllocatedSpace += realAllocSize;
526 
527  return workingOffset;
528  } else {
529  // An area is taken from the bins,
530  long freeAreaOffset;
531  var headerInfo = new long[2];
532 
533  // Remove this area from the bin chain and possibly add any excess space
534  // left over to a new bin.
535  if (prevOffset == -1) {
536  freeAreaOffset = freeBinList[foundBinIndex];
537  ReadAreaHeader(freeAreaOffset, headerInfo);
538  freeBinList[foundBinIndex] = headerInfo[1];
539  WriteBinIndex(foundBinIndex);
540  } else {
541  var headerInfo2 = new long[2];
542  ReadAreaHeader(prevOffset, headerInfo2);
543  freeAreaOffset = headerInfo2[1];
544  ReadAreaHeader(freeAreaOffset, headerInfo);
545  headerInfo2[1] = headerInfo[1];
546  ReboundArea(prevOffset, headerInfo2, false);
547  }
548 
549  // Reset the header of the recycled area.
550  headerInfo[0] = (headerInfo[0] & ActiveFlag);
551  ReboundArea(freeAreaOffset, headerInfo, true);
552 
553  // Crop the area to the given size.
554  CropArea(freeAreaOffset, size);
555 
556  // Add to the total allocated space
557  totalAllocatedSpace += realAllocSize;
558 
559  return freeAreaOffset;
560  }
561  }
void CropArea(long offset, long allocatedSize)
Definition: StoreBase.cs:372
abstract long DataAreaEndOffset
Definition: StoreBase.cs:80
static int MinimumBinSizeIndex(long size)
Definition: StoreBase.cs:89
void ReboundArea(long offset, long[] header, bool writeHeaders)
Definition: StoreBase.cs:350
static readonly int MaxBinSize
Definition: StoreBase.cs:47
void CoalesceArea(long offset, long size)
Definition: StoreBase.cs:361
void RemoveFromBinChain(long offset, long size)
Definition: StoreBase.cs:205
void WriteBinIndex(int index)
Definition: StoreBase.cs:118
long ExpandDataArea(long minSize)
Definition: StoreBase.cs:564
void ReadAreaHeader(long offset, long[] header)
Definition: StoreBase.cs:342
static readonly int BinSizeEntries
Definition: StoreBase.cs:46
void Deveel.Data.Store.StoreBase.CheckOffset ( long  offset)
inlineprivate

Definition at line 82 of file StoreBase.cs.

82  {
83  if (offset < DataAreaOffset || offset >= DataAreaEndOffset) {
84  throw new IOException(String.Format("The offset is out of range ({0} > {1} > {2})", DataAreaOffset, offset,
86  }
87  }
abstract long DataAreaEndOffset
Definition: StoreBase.cs:80
A long string in the system.
void Deveel.Data.Store.StoreBase.Close ( )
inline

Definition at line 728 of file StoreBase.cs.

728  {
729  lock (this) {
730  // Mark the file as closed
731  if (!IsReadOnly)
732  Write(16, 0);
733 
734  CloseStore();
735  }
736  }
abstract void CloseStore()
void Write(long offset, byte value)
Definition: StoreBase.cs:876
abstract void Deveel.Data.Store.StoreBase.CloseStore ( )
protectedpure virtual
void Deveel.Data.Store.StoreBase.CoalesceArea ( long  offset,
long  size 
)
inlineprivate

Definition at line 361 of file StoreBase.cs.

361  {
362  ByteBuffer.WriteInt8(size, headerBuf, 0);
363 
364  // ISSUE: Boundary alteration is a moment when corruption could occur.
365  // There are two seeks and writes here and when we are setting the
366  // end points, there is a risk of failure.
367 
368  Write(offset, headerBuf, 0, 8);
369  Write((offset + size) - 8, headerBuf, 0, 8);
370  }
readonly byte[] headerBuf
Definition: StoreBase.cs:348
void Write(long offset, byte value)
Definition: StoreBase.cs:876
A wrapper for an array of byte.
Definition: ByteBuffer.cs:27
static void WriteInt8(long value, byte[] arr, int offset)
Definition: ByteBuffer.cs:252
IArea Deveel.Data.Store.StoreBase.CreateArea ( long  size)
inline

Allocates a block of memory in the store of the specified size and returns an IArea object that can be used to initialize the contents of the area.

Parameters
sizeThe amount of memory to allocate.

Note that an area in the store is undefined until the IArea.Flush method is called in IArea.

Returns
Returns an IArea object that allows the area to be setup.
Exceptions
System.IO.IOExceptionIf not enough space available to create the area or the store is Read-only.

Implements Deveel.Data.Store.IStore.

Definition at line 755 of file StoreBase.cs.

755  {
756  lock (this) {
757  long pointer = Alloc(size);
758  return new StoreArea(this, pointer, pointer + 8, false, size);
759  }
760  }
long Alloc(long size)
Definition: StoreBase.cs:408
void Deveel.Data.Store.StoreBase.CropArea ( long  offset,
long  allocatedSize 
)
inlineprivate

Definition at line 372 of file StoreBase.cs.

372  {
373  // Get the header info
374  var headerInfo = new long[2];
375  ReadAreaHeader(offset, headerInfo);
376 
377  var header = headerInfo[0];
378 
379  var freeAreaSize = header;
380  var sizeDifference = freeAreaSize - allocatedSize;
381  var isWilderness = (offset == WildernessOffset);
382 
383  // If the difference is greater than 512 bytes, add the excess space to
384  // a free bin.
385 
386  if ((isWilderness && sizeDifference >= 32) || sizeDifference >= 512) {
387  // Split the area into two areas.
388  SplitArea(offset, allocatedSize);
389 
390  long leftOverPointer = offset + allocatedSize;
391  // Add this area to the bin chain
392  AddToBinChain(leftOverPointer, sizeDifference);
393 
394  // If offset is the wilderness area, set this as the new wilderness
395  if (isWilderness ||
396  (leftOverPointer + sizeDifference) >= DataAreaEndOffset) {
397  WildernessOffset = leftOverPointer;
398  }
399 
400  } else {
401  // If offset is the wilderness area, set wilderness to -1
402  if (isWilderness) {
403  WildernessOffset = -1;
404  }
405  }
406  }
abstract long DataAreaEndOffset
Definition: StoreBase.cs:80
void SplitArea(long offset, long newBoundary)
Definition: StoreBase.cs:585
void ReadAreaHeader(long offset, long[] header)
Definition: StoreBase.cs:342
void AddToBinChain(long pointer, long size)
Definition: StoreBase.cs:125
void Deveel.Data.Store.StoreBase.DeleteArea ( long  id)
inline

Deletes an area that was previously allocated by the CreateArea method by the area id.

Parameters
idThe identifier of the area to delete.

Once an area is deleted the resources may be reclaimed. The behaviour of this method is undefined if the id doesn't represent a valid area.

Exceptions
IOExceptionIf the id is invalid or the area can not otherwise by deleted.

Implements Deveel.Data.Store.IStore.

Definition at line 762 of file StoreBase.cs.

762  {
763  lock (this) {
764  Free(id);
765  }
766  }
void Free(long pointer)
Definition: StoreBase.cs:245
void Deveel.Data.Store.StoreBase.Dispose ( )
inline

Definition at line 738 of file StoreBase.cs.

738  {
739  Dispose(true);
740  GC.SuppressFinalize(this);
741  }
virtual void Deveel.Data.Store.StoreBase.Dispose ( bool  disposing)
inlineprotectedvirtual

Reimplemented in Deveel.Data.Store.SingleFileStore.

Definition at line 745 of file StoreBase.cs.

745  {
746  if (!disposed) {
747  if (disposing) {
748  Close();
749  }
750 
751  disposed = true;
752  }
753  }
long Deveel.Data.Store.StoreBase.ExpandDataArea ( long  minSize)
inlineprivate

Definition at line 564 of file StoreBase.cs.

564  {
565  long endOfDataArea = DataAreaEndOffset;
566 
567  // Round all sizes up to the nearest 8
568  // We grow only by a small amount if the area is small, and a large amount
569  // if the area is large.
570  long overGrow = endOfDataArea / 64;
571  long d = (overGrow & 0x07L);
572  if (d != 0)
573  overGrow = overGrow + (8 - d);
574 
575  overGrow = System.Math.Min(overGrow, 262144L);
576  if (overGrow < 1024)
577  overGrow = 1024;
578 
579  long growBy = minSize + overGrow;
580  long newFileLength = endOfDataArea + growBy;
581  SetDataAreaSize(newFileLength);
582  return growBy;
583  }
abstract long DataAreaEndOffset
Definition: StoreBase.cs:80
abstract void SetDataAreaSize(long length)
IEnumerable<long> Deveel.Data.Store.StoreBase.FindAllocatedAreasNotIn ( List< long >  usedAreas)
inlinepackage

Definition at line 806 of file StoreBase.cs.

806  {
807  // Sort the list
808  var list = new List<long>(usedAreas);
809  list.Sort();
810 
811  // The list of leaked areas
812  var leakedAreas = new List<long>();
813 
814  int listIndex = 0;
815 
816  // What area are we looking for?
817  long lookingFor = Int64.MaxValue;
818  if (listIndex < list.Count) {
819  lookingFor = list[listIndex];
820  ++listIndex;
821  }
822 
823  long endOfDataArea = DataAreaEndOffset;
824  long[] header = new long[2];
825 
826  long offset = DataAreaOffset;
827  while (offset < endOfDataArea) {
828  ReadAreaHeader(offset, header);
829 
830  long areaSize = (header[0] & ActiveFlag);
831  bool areaFree = (header[0] & DeletedFlag) != 0;
832 
833  if (offset == lookingFor) {
834  if (areaFree)
835  throw new IOException("Area is not allocated!");
836 
837  // Update the 'looking_for' offset
838  if (listIndex < list.Count) {
839  lookingFor = (long)list[listIndex];
840  ++listIndex;
841  } else {
842  lookingFor = Int64.MaxValue;
843  }
844  } else if (offset > lookingFor) {
845  throw new IOException("IArea (offset = " + lookingFor + ") wasn't found input store!");
846  } else {
847  // An area that isn't input the list
848  if (!areaFree) {
849  // This is a leaked area.
850  // It isn't free and it isn't input the list
851  leakedAreas.Add(offset);
852  }
853  }
854 
855  offset += areaSize;
856  }
857 
858  return leakedAreas.ToArray();
859  }
abstract long DataAreaEndOffset
Definition: StoreBase.cs:80
void ReadAreaHeader(long offset, long[] header)
Definition: StoreBase.cs:342
void Deveel.Data.Store.StoreBase.Free ( long  pointer)
inlineprivate

Definition at line 245 of file StoreBase.cs.

245  {
246  // Get the area header
247  var headerInfo = new long[2];
248  ReadAreaHeader(pointer, headerInfo);
249 
250  if ((headerInfo[0] & DeletedFlag) != 0)
251  throw new IOException("Area already marked as unallocated.");
252 
253  // If (pointer + size) reaches the end of the header area, set this as the
254  // wilderness.
255  bool setAsWilderness = ((pointer + headerInfo[0]) >= DataAreaEndOffset);
256 
257  var rOffset = pointer;
258  var freeingAreaSize = headerInfo[0];
259  var rSize = freeingAreaSize;
260 
261  // Can this area coalesce?
262  var headerInfo2 = new long[2];
263  var leftPointer = GetPreviousAreaHeader(pointer, headerInfo2);
264  var coalesc = false;
265 
266  if ((headerInfo2[0] & DeletedFlag) != 0) {
267  // Yes, we can coalesce left
268  long areaSize = (headerInfo2[0] & ActiveFlag);
269 
270  rOffset = leftPointer;
271  rSize = rSize + areaSize;
272 
273  // Remove left area from the bin
274  RemoveFromBinChain(leftPointer, areaSize);
275  coalesc = true;
276  }
277 
278  if (!setAsWilderness) {
279  long rightPointer = GetNextAreaHeader(pointer, headerInfo2);
280  if ((headerInfo2[0] & DeletedFlag) != 0) {
281  // Yes, we can coalesce right
282  long areaSize = (headerInfo2[0] & ActiveFlag);
283 
284  rSize = rSize + areaSize;
285 
286  // Remove right from the bin
287  RemoveFromBinChain(rightPointer, areaSize);
288  setAsWilderness = (rightPointer == WildernessOffset);
289  coalesc = true;
290  }
291  }
292 
293  // If we are coalescing parent areas
294  if (coalesc)
295  CoalesceArea(rOffset, rSize);
296 
297  // Add this new area to the bin chain,
298  AddToBinChain(rOffset, rSize);
299 
300  // Do we set this as the wilderness?
301  if (setAsWilderness)
302  WildernessOffset = rOffset;
303 
304  totalAllocatedSpace -= freeingAreaSize;
305  }
abstract long DataAreaEndOffset
Definition: StoreBase.cs:80
long GetPreviousAreaHeader(long offset, long[] header)
Definition: StoreBase.cs:308
long GetNextAreaHeader(long offset, long[] header)
Definition: StoreBase.cs:325
void CoalesceArea(long offset, long size)
Definition: StoreBase.cs:361
void RemoveFromBinChain(long offset, long size)
Definition: StoreBase.cs:205
void ReadAreaHeader(long offset, long[] header)
Definition: StoreBase.cs:342
void AddToBinChain(long pointer, long size)
Definition: StoreBase.cs:125
IEnumerable<long> Deveel.Data.Store.StoreBase.GetAllAreas ( )
inline

Returns a complete list of pointers to all areas in the Store as long objects sorted from lowest pointer to highest.

This should be used for diagnostics only because it may be difficult for this to be generated with some implementations. It is useful in a repair tool to determine if a pointer is valid or not.

Returns
Returns an implementation of IList that contains all the pointers (as long) to the areas from the lowest to the highest.

Implements Deveel.Data.Store.IStore.

Definition at line 785 of file StoreBase.cs.

785  {
786  var list = new List<long>();
787 
788  long endOfDataArea = DataAreaEndOffset;
789 
790  long[] header = new long[2];
791  // The first header
792  long offset = DataAreaOffset;
793  while (offset < endOfDataArea) {
794  ReadAreaHeader(offset, header);
795 
796  long areaSize = (header[0] & ActiveFlag);
797  if ((header[0] & DeletedFlag) == 0)
798  list.Add(offset);
799 
800  offset += areaSize;
801  }
802 
803  return list;
804  }
abstract long DataAreaEndOffset
Definition: StoreBase.cs:80
void ReadAreaHeader(long offset, long[] header)
Definition: StoreBase.cs:342
IArea Deveel.Data.Store.StoreBase.GetArea ( long  id,
bool  readOnly 
)
inline

Returns an object that allows for the contents of an area (represented by the id parameter) to be Read.

Parameters
idThe identifier of the area to Read, or -1 for a 64 byte fixed area in the store.
readOnlyIndicates if the returned area must be read-only.

The behaviour of this method is undefined if the id doesn't represent a valid area.

When id is -1 then a fixed area (64 bytes in size) in the store is returned. The fixed area can be used to store important static information.

Returns
Returns an IArea object that allows access to the part of the store.
Exceptions
IOExceptionIf the id is invalid or the area can not otherwise be accessed.

Implements Deveel.Data.Store.IStore.

Definition at line 768 of file StoreBase.cs.

768  {
769  // If this is the fixed area
770  if (id == -1)
771  return new StoreArea(this, id, FixedAreaOffset, readOnly, 64);
772 
773  // Otherwise must be a regular area
774  return new StoreArea(this, id, id, readOnly);
775  }
long Deveel.Data.Store.StoreBase.GetNextAreaHeader ( long  offset,
long[]  header 
)
inlineprivate

Definition at line 325 of file StoreBase.cs.

325  {
326  Read(offset, headerBuf, 0, 8);
327  long sz = ByteBuffer.ReadInt8(headerBuf, 0);
328  sz = sz & ActiveFlag;
329  long nextOffset = offset + sz;
330 
331  if (nextOffset >= DataAreaEndOffset) {
332  // Return a 0 sized block
333  header[0] = 0;
334  return -1;
335  }
336 
337  Read(nextOffset, headerBuf, 0, 8);
338  header[0] = ByteBuffer.ReadInt8(headerBuf, 0);
339  return nextOffset;
340  }
abstract long DataAreaEndOffset
Definition: StoreBase.cs:80
readonly byte[] headerBuf
Definition: StoreBase.cs:348
abstract int Read(long offset, byte[] buffer, int index, int length)
A wrapper for an array of byte.
Definition: ByteBuffer.cs:27
static long ReadInt8(byte[] arr, int offset)
Definition: ByteBuffer.cs:234
long Deveel.Data.Store.StoreBase.GetPreviousAreaHeader ( long  offset,
long[]  header 
)
inlineprivate

Definition at line 308 of file StoreBase.cs.

308  {
309  // If the offset is the start of the file area
310  if (offset == DataAreaOffset) {
311  // Return a 0 sized block
312  header[0] = 0;
313  return -1;
314  }
315 
316  Read(offset - 8, headerBuf, 0, 8);
317  long sz = ByteBuffer.ReadInt8(headerBuf, 0);
318  sz = sz & ActiveFlag;
319  long previousPointer = offset - sz;
320  Read(previousPointer, headerBuf, 0, 8);
321  header[0] = ByteBuffer.ReadInt8(headerBuf, 0);
322  return previousPointer;
323  }
readonly byte[] headerBuf
Definition: StoreBase.cs:348
abstract int Read(long offset, byte[] buffer, int index, int length)
A wrapper for an array of byte.
Definition: ByteBuffer.cs:27
static long ReadInt8(byte[] arr, int offset)
Definition: ByteBuffer.cs:234
void Deveel.Data.Store.StoreBase.Init ( )
inlineprivate

Definition at line 615 of file StoreBase.cs.

615  {
616  lock (this) {
618 
619  using (var stream = new MemoryStream((int) BinAreaOffset)) {
620  using (BinaryWriter writer = new BinaryWriter(stream, Encoding.Unicode)) {
621 
622  // The file MAGIC
623  writer.Write(Magic); // 0
624 
625  // The file version
626  writer.Write(1); // 4
627 
628  // The number of areas (chunks) input the file (currently unused)
629  writer.Write(-1L); // 8
630 
631  // File open/close status byte
632  writer.Write((byte) 0); // 16
633 
634  writer.Flush();
635 
636  byte[] buffer = new byte[(int) DataAreaOffset];
637  byte[] temp = stream.ToArray();
638  Array.Copy(temp, 0, buffer, 0, temp.Length);
639 
640  for (int i = (int) BinAreaOffset; i < (int) DataAreaOffset; ++i) {
641  buffer[i] = 255;
642  }
643 
644  Write(0, buffer, 0, buffer.Length);
645  }
646  }
647  }
648  }
void Write(long offset, byte value)
Definition: StoreBase.cs:876
abstract void SetDataAreaSize(long length)
static bool Deveel.Data.Store.StoreBase.IsValidBoundarySize ( long  size)
inlinestaticprivate

Definition at line 609 of file StoreBase.cs.

609  {
610  const long maxAreaSize = (long)Int32.MaxValue * 200;
611  size = size & ActiveFlag;
612  return ((size < maxAreaSize) && (size >= 24) && ((size & 0x07) == 0));
613  }
abstract void Deveel.Data.Store.StoreBase.Lock ( )
pure virtual

This method is called before the start of a sequence of Write commands between consistant states of some data structure represented by the store.

This Lock mechanism is intended to inform the store when it is not safe to checkpoint the data in a log, ensuring that no partial updates are committed to a transaction log and the data can be restored in a consistant manner.

If the store does not implement a check point log or is otherwise not interested in consistant states of the data, then it is not necessary for this method to do anything.

This method prevents a check point from happening during some sequence of operations. This method should not Lock unless a check point is in progress. This method does not prevent concurrent writes to the store.

See also
Unlock

Implements Deveel.Data.Store.IStore.

Implemented in Deveel.Data.Store.SingleFileStore.

static int Deveel.Data.Store.StoreBase.MinimumBinSizeIndex ( long  size)
inlinestaticprivate

Definition at line 89 of file StoreBase.cs.

89  {
90  int i = Array.BinarySearch(BinSizes, (int)size);
91  if (i < 0) {
92  i = -(i + 1);
93  }
94  return i;
95  }
static readonly int[] BinSizes
Definition: StoreBase.cs:31
bool Deveel.Data.Store.StoreBase.Open ( )
inline

Definition at line 653 of file StoreBase.cs.

653  {
654  lock (this) {
656 
657  // If it's small, initialize to empty
659  Init();
660 
661  byte[] readBuf = new byte[(int) BinAreaOffset];
662  Read(0, readBuf, 0, readBuf.Length);
663 
664  using (var stream = new MemoryStream(readBuf)) {
665  using (var reader = new BinaryReader(stream)) {
666 
667  int magic = reader.ReadInt32();
668  if (magic != Magic)
669  throw new IOException("Format invalid: Magic value is not as expected.");
670 
671  int version = reader.ReadInt32();
672  if (version != 1)
673  throw new IOException("Format invalid: unrecognized version.");
674 
675  reader.ReadInt64(); // ignore
676  byte status = reader.ReadByte();
677  ClosedClean = true;
678 
679  if (status == 1) {
680  // This means the store wasn't closed cleanly.
681  ClosedClean = false;
682  }
683  }
684  }
685 
686  // Read the bins
687  ReadBins();
688 
689  // Mark the file as open
690  if (!IsReadOnly)
691  Write(16, 1);
692 
693  long fileLength = DataAreaEndOffset;
694  if (fileLength <= 8) {
695  throw new IOException("Format invalid: File size is too small.");
696  }
697 
698  // Set the wilderness offset.
699  if (fileLength == DataAreaOffset) {
700  WildernessOffset = -1;
701  } else {
702  Read(fileLength - 8, readBuf, 0, 8);
703  long lastBoundary = ByteBuffer.ReadInt8(readBuf, 0);
704  long lastAreaPointer = fileLength - lastBoundary;
705 
706  if (lastAreaPointer < DataAreaOffset)
707  throw new IOException("File corrupt: last area offset is before data part of file.");
708 
709  if (lastAreaPointer > fileLength - 8)
710  throw new IOException("File corrupt: last_area_pointer at the end of the file.");
711 
712  Read(lastAreaPointer, readBuf, 0, 8);
713 
714  long lastAreaHeader = ByteBuffer.ReadInt8(readBuf, 0);
715 
716  // If this is a freed block, then set this are the wilderness offset.
717  if ((lastAreaHeader & DeletedFlag) != 0) {
718  WildernessOffset = lastAreaPointer;
719  } else {
720  WildernessOffset = -1;
721  }
722  }
723 
724  return ClosedClean;
725  }
726  }
abstract long DataAreaEndOffset
Definition: StoreBase.cs:80
abstract void OpenStore(bool readOnly)
void Write(long offset, byte value)
Definition: StoreBase.cs:876
abstract int Read(long offset, byte[] buffer, int index, int length)
A wrapper for an array of byte.
Definition: ByteBuffer.cs:27
static long ReadInt8(byte[] arr, int offset)
Definition: ByteBuffer.cs:234
abstract void Deveel.Data.Store.StoreBase.OpenStore ( bool  readOnly)
protectedpure virtual
abstract int Deveel.Data.Store.StoreBase.Read ( long  offset,
byte[]  buffer,
int  index,
int  length 
)
protectedpure virtual
void Deveel.Data.Store.StoreBase.ReadAreaHeader ( long  offset,
long[]  header 
)
inlineprotected

Definition at line 342 of file StoreBase.cs.

342  {
343  Read(offset, headerBuf, 0, 16);
344  header[0] = ByteBuffer.ReadInt8(headerBuf, 0);
345  header[1] = ByteBuffer.ReadInt8(headerBuf, 8);
346  }
readonly byte[] headerBuf
Definition: StoreBase.cs:348
abstract int Read(long offset, byte[] buffer, int index, int length)
A wrapper for an array of byte.
Definition: ByteBuffer.cs:27
static long ReadInt8(byte[] arr, int offset)
Definition: ByteBuffer.cs:234
void Deveel.Data.Store.StoreBase.ReadBins ( )
inlineprivate

Definition at line 97 of file StoreBase.cs.

97  {
98  Read(BinAreaOffset, binArea, 0, 128 * 8);
99  using (var bin = new MemoryStream(binArea)) {
100  using (BinaryReader input = new BinaryReader(bin)) {
101  for (int i = 0; i < 128; ++i) {
102  freeBinList[i] = input.ReadInt64();
103  }
104  }
105  }
106  }
abstract int Read(long offset, byte[] buffer, int index, int length)
readonly byte[] binArea
Definition: StoreBase.cs:29
int Deveel.Data.Store.StoreBase.ReadByte ( long  offset)
inlineprotected

Definition at line 865 of file StoreBase.cs.

865  {
866  var buffer = new byte[1];
867  var count = Read(offset, buffer, 0, 1);
868  if (count == 0)
869  return -1;
870 
871  return buffer[0];
872  }
abstract int Read(long offset, byte[] buffer, int index, int length)
void Deveel.Data.Store.StoreBase.ReboundArea ( long  offset,
long[]  header,
bool  writeHeaders 
)
inlineprivate

Definition at line 350 of file StoreBase.cs.

350  {
351  if (writeHeaders) {
352  ByteBuffer.WriteInt8(header[0], headerBuf, 0);
353  ByteBuffer.WriteInt8(header[1], headerBuf, 8);
354  Write(offset, headerBuf, 0, 16);
355  } else {
356  ByteBuffer.WriteInt8(header[1], headerBuf, 8);
357  Write(offset + 8, headerBuf, 8, 8);
358  }
359  }
readonly byte[] headerBuf
Definition: StoreBase.cs:348
void Write(long offset, byte value)
Definition: StoreBase.cs:876
A wrapper for an array of byte.
Definition: ByteBuffer.cs:27
static void WriteInt8(long value, byte[] arr, int offset)
Definition: ByteBuffer.cs:252
void Deveel.Data.Store.StoreBase.RemoveFromBinChain ( long  offset,
long  size 
)
inlineprivate

Definition at line 205 of file StoreBase.cs.

205  {
206  // What bin index should we be looking input?
207  int binChainIndex = MinimumBinSizeIndex(size);
208 
209  var prevOffset = -1L;
210  var curOffset = freeBinList[binChainIndex];
211 
212  // Search this bin for the offset
213  // NOTE: This is an iterative search through the bin chain
214  while (offset != curOffset) {
215  if (curOffset == -1)
216  throw new IOException("Area not found input bin chain.");
217 
218  // Move to the next input the chain
219  var headerInfo = new long[2];
220  ReadAreaHeader(curOffset, headerInfo);
221 
222  prevOffset = curOffset;
223  curOffset = headerInfo[1];
224  }
225 
226  // Found the offset, so remove it,
227  if (prevOffset == -1) {
228  var headerInfo = new long[2];
229 
230  ReadAreaHeader(offset, headerInfo);
231  freeBinList[binChainIndex] = headerInfo[1];
232  WriteBinIndex(binChainIndex);
233  } else {
234  var headerInfo = new long[2];
235  var headerInfo2 = new long[2];
236 
237  ReadAreaHeader(prevOffset, headerInfo2);
238  ReadAreaHeader(offset, headerInfo);
239  headerInfo2[1] = headerInfo[1];
240  ReboundArea(prevOffset, headerInfo2, false);
241  }
242 
243  }
static int MinimumBinSizeIndex(long size)
Definition: StoreBase.cs:89
void ReboundArea(long offset, long[] header, bool writeHeaders)
Definition: StoreBase.cs:350
void WriteBinIndex(int index)
Definition: StoreBase.cs:118
void ReadAreaHeader(long offset, long[] header)
Definition: StoreBase.cs:342
abstract void Deveel.Data.Store.StoreBase.SetDataAreaSize ( long  length)
protectedpure virtual
void Deveel.Data.Store.StoreBase.SplitArea ( long  offset,
long  newBoundary 
)
inlineprotected

Definition at line 585 of file StoreBase.cs.

585  {
586  // Split the area pointed to by the offset.
587  Read(offset, headerBuf, 0, 8);
588  long curSize = ByteBuffer.ReadInt8(headerBuf, 0) & ActiveFlag;
589  long leftSize = newBoundary;
590  long rightSize = curSize - newBoundary;
591 
592  if (rightSize < 0)
593  throw new IOException("Could not split the area.");
594 
595  ByteBuffer.WriteInt8(leftSize, headerBuf, 0);
596  ByteBuffer.WriteInt8(rightSize, headerBuf, 8);
597 
598  // ISSUE: Boundary alteration is a moment when corruption could occur.
599  // There are three seeks and writes here and when we are setting the
600  // end points, there is a risk of failure.
601 
602  // First set the boundary
603  Write((offset + newBoundary) - 8, headerBuf, 0, 16);
604  // Now set the end points
605  Write(offset, headerBuf, 0, 8);
606  Write((offset + curSize) - 8, headerBuf, 8, 8);
607  }
readonly byte[] headerBuf
Definition: StoreBase.cs:348
void Write(long offset, byte value)
Definition: StoreBase.cs:876
abstract int Read(long offset, byte[] buffer, int index, int length)
A wrapper for an array of byte.
Definition: ByteBuffer.cs:27
static long ReadInt8(byte[] arr, int offset)
Definition: ByteBuffer.cs:234
static void WriteInt8(long value, byte[] arr, int offset)
Definition: ByteBuffer.cs:252
abstract void Deveel.Data.Store.StoreBase.Unlock ( )
pure virtual

This method is called after the end of a sequence of Write commands between consistant states of some data structure represented by the store.

See the Lock method for a further description of the operation of this locking mechanism.

See also
Lock

Implements Deveel.Data.Store.IStore.

Implemented in Deveel.Data.Store.SingleFileStore.

void Deveel.Data.Store.StoreBase.Write ( long  offset,
byte  value 
)
inlineprotected

Definition at line 876 of file StoreBase.cs.

876  {
877  Write(offset, new []{value}, 0, 1);
878  }
void Write(long offset, byte value)
Definition: StoreBase.cs:876
abstract void Deveel.Data.Store.StoreBase.Write ( long  offset,
byte[]  buffer,
int  index,
int  length 
)
protectedpure virtual
void Deveel.Data.Store.StoreBase.WriteAllBins ( )
inlineprivate

Definition at line 108 of file StoreBase.cs.

108  {
109  int p = 0;
110  for (int i = 0; i < 128; ++i, p += 8) {
111  long val = freeBinList[i];
112  ByteBuffer.WriteInt8(val, binArea, p);
113  }
114 
115  Write(BinAreaOffset, binArea, 0, 128 * 8);
116  }
void Write(long offset, byte value)
Definition: StoreBase.cs:876
readonly byte[] binArea
Definition: StoreBase.cs:29
A wrapper for an array of byte.
Definition: ByteBuffer.cs:27
static void WriteInt8(long value, byte[] arr, int offset)
Definition: ByteBuffer.cs:252
void Deveel.Data.Store.StoreBase.WriteBinIndex ( int  index)
inlineprivate

Definition at line 118 of file StoreBase.cs.

118  {
119  int p = index * 8;
120  long val = freeBinList[index];
121  ByteBuffer.WriteInt8(val, binArea, p);
122  Write(BinAreaOffset + p, binArea, p, 8);
123  }
void Write(long offset, byte value)
Definition: StoreBase.cs:876
readonly byte[] binArea
Definition: StoreBase.cs:29
A wrapper for an array of byte.
Definition: ByteBuffer.cs:27
static void WriteInt8(long value, byte[] arr, int offset)
Definition: ByteBuffer.cs:252

Member Data Documentation

const long Deveel.Data.Store.StoreBase.ActiveFlag = Int64.MaxValue
private

Definition at line 49 of file StoreBase.cs.

readonly byte [] Deveel.Data.Store.StoreBase.binArea = new byte[128 * 8]
private

Definition at line 29 of file StoreBase.cs.

const long Deveel.Data.Store.StoreBase.BinAreaOffset = 256
private

Definition at line 57 of file StoreBase.cs.

readonly int Deveel.Data.Store.StoreBase.BinSizeEntries = BinSizes.Length
staticprivate

Definition at line 46 of file StoreBase.cs.

readonly int [] Deveel.Data.Store.StoreBase.BinSizes
staticprivate
Initial value:
=
{
32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 480,
512, 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928,
960, 992, 1024, 1056, 1088, 1120, 1152, 1184, 1216, 1248, 1280, 1312,
1344, 1376, 1408, 1440, 1472, 1504, 1536, 1568, 1600, 1632, 1664, 1696,
1728, 1760, 1792, 1824, 1856, 1888, 1920, 1952, 1984, 2016, 2048, 2080,
2144, 2208, 2272, 2336, 2400, 2464, 2528, 2592, 2656, 2720, 2784, 2848,
2912, 2976, 3040, 3104, 3168, 3232, 3296, 3360, 3424, 3488, 3552, 3616,
3680, 3744, 3808, 3872, 3936, 4000, 4064, 4128, 4384, 4640, 4896, 5152,
5408, 5664, 5920, 6176, 6432, 6688, 6944, 7200, 7456, 7712, 7968, 8224,
10272, 12320, 14368, 16416, 18464, 20512, 22560, 24608, 57376, 90144,
122912, 155680, 1204256, 2252832
}

Definition at line 31 of file StoreBase.cs.

const long Deveel.Data.Store.StoreBase.DataAreaOffset = 256 + 1024 + 32
private

Definition at line 55 of file StoreBase.cs.

const long Deveel.Data.Store.StoreBase.DeletedFlag = Int64.MinValue
private

Definition at line 50 of file StoreBase.cs.

bool Deveel.Data.Store.StoreBase.disposed
private

Definition at line 743 of file StoreBase.cs.

const long Deveel.Data.Store.StoreBase.FixedAreaOffset = 128
private

Definition at line 52 of file StoreBase.cs.

long [] Deveel.Data.Store.StoreBase.freeBinList
private

Definition at line 26 of file StoreBase.cs.

readonly byte [] Deveel.Data.Store.StoreBase.headerBuf = new byte[16]
private

Definition at line 348 of file StoreBase.cs.

const int Deveel.Data.Store.StoreBase.Magic = 0x0AEAE91
private

Definition at line 59 of file StoreBase.cs.

readonly int Deveel.Data.Store.StoreBase.MaxBinSize = BinSizes[BinSizeEntries - 1]
staticprivate

Definition at line 47 of file StoreBase.cs.

long Deveel.Data.Store.StoreBase.totalAllocatedSpace
private

Definition at line 27 of file StoreBase.cs.

Property Documentation

bool Deveel.Data.Store.StoreBase.ClosedClean
getprivate set

Definition at line 783 of file StoreBase.cs.

abstract long Deveel.Data.Store.StoreBase.DataAreaEndOffset
getprotected

Definition at line 80 of file StoreBase.cs.

bool Deveel.Data.Store.StoreBase.IsReadOnly
getprivate set

Definition at line 78 of file StoreBase.cs.

long Deveel.Data.Store.StoreBase.WildernessOffset
getsetprivate

Definition at line 76 of file StoreBase.cs.


The documentation for this class was generated from the following file: