public List <IComparable> GetLastRowFromTable(TableDefinition tableDefinition) { Stack <long> pointers = new Stack <long>(); long dataPosition = tableDefinition.DataAddress; pointers.Push(dataPosition); while (PageIsFull(dataPosition, tableDefinition.GetRowSizeInBytes())) { dataPosition = PageLocationHelper.GetNextPagePointer(dataPosition); pointers.Push(dataPosition); } using (FileStream fs = new FileStream(Constants.FILE_NAME, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (BinaryReader binaryReader = new BinaryReader(fs)) { List <List <IComparable> > rowsFromLastPage = ReadDataFromPage(dataPosition, tableDefinition.ColumnDefinitions, binaryReader); if (!rowsFromLastPage.Any()) { //if there are no rows, then the last row is on the previous page pointers.Pop(); //remove last pointer, which is a pointer to an empty page long previousAddress = pointers.Pop(); rowsFromLastPage = ReadDataFromPage(previousAddress, tableDefinition.ColumnDefinitions, binaryReader); } return(rowsFromLastPage.Last()); } } }
public long GetFirstAvailableDataAddress(long dataStart, int objectSize) { while (PageIsFull(dataStart, objectSize)) { dataStart = PageLocationHelper.GetNextPagePointer(dataStart); } using (FileStream fileStream = new FileStream(Constants.FILE_NAME, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { fileStream.Position = dataStart; using (BinaryReader binaryReader = new BinaryReader(fileStream)) { short numObjects = binaryReader.ReadInt16(); return(objectSize * numObjects + 2 + dataStart);//todo: use global 2 byte integer size } } }