internal Sector GetOrReadSector(SectorPtr sectorPtr, bool inWriteTransaction, SectorTypeInit typeInit, Sector parent) { return TryGetSector(sectorPtr.Ptr, inWriteTransaction, parent) ?? ReadSector(sectorPtr, inWriteTransaction, typeInit, parent); }
internal Sector ReadSector(SectorPtr sectorPtr, bool inWriteTransaction, SectorTypeInit typeInit, Sector parent) { Debug.Assert(sectorPtr.Ptr > 0); return ReadSector(sectorPtr.Ptr & MaskOfPosition, (int)(sectorPtr.Ptr & MaskOfGranLength) + 1, sectorPtr.Checksum, inWriteTransaction, typeInit, parent); }
Sector ReadSector(long position, int size, uint checksum, bool inWriteTransaction, SectorTypeInit typeInit, Sector parent) { if (position <= 0) throw new BTDBException("Wrong data in db (negative position)"); if (size <= 0 || size > MaxSectorSize / AllocationGranularity) throw new BTDBException("Wrong sector length"); TruncateSectorCache(inWriteTransaction, parent != null ? parent.Position : 0); lock (_readSectorLock) { Sector sector = TryGetSector(position,inWriteTransaction,parent); if (sector != null) return sector; size = size * AllocationGranularity; sector = new Sector { Position = position, Length = size, InternalLastAccessTime = 0, Parent = parent }; if (inWriteTransaction) { sector.InTransaction = _spaceAllocatedInTransaction.Contains((ulong)position); if (sector.InTransaction) LinkToTailOfInTransactionSectors(sector); } //Console.WriteLine("Reading {0} len:{1}", position, size); if (_positionLessStream.Read(sector.Data, 0, size, (ulong)position) != size) { throw new BTDBException("Data reading error"); } Interlocked.Add(ref _totalBytesRead, size); if (Checksum.CalcFletcher32(sector.Data, 0, (uint)size) != checksum) { throw new BTDBException("Checksum error"); } switch (typeInit) { case SectorTypeInit.AllocChild: sector.Type = SectorType.AllocChild; break; case SectorTypeInit.AllocParent: sector.Type = SectorType.AllocParent; break; case SectorTypeInit.DataParent: sector.Type = SectorType.DataParent; break; case SectorTypeInit.DataChild: sector.Type = SectorType.DataChild; break; case SectorTypeInit.BTreeChildOrParent: sector.Type = BTreeChildIterator.IsChildFromSectorData(sector.Data) ? SectorType.BTreeChild : SectorType.BTreeParent; break; default: throw new InvalidOperationException(); } LowLevelAddToSectorCache(sector); UpdateLastAccess(sector); if (inWriteTransaction) { sector.Parent = parent; } return sector; } }