private void FlushIfHeaderBlockPage(CachedIoAdapter.Page page) { if (ContainsHeaderBlock(page)) { FlushPage(page); } }
private void MovePageToHead(CachedIoAdapter.Page page) { if (page == _head) { return; } if (page == _tail) { CachedIoAdapter.Page tempTail = _tail._prev; tempTail._next = null; _tail._next = _head; _tail._prev = null; _head._prev = page; _head = _tail; _tail = tempTail; } else { page._prev._next = page._next; page._next._prev = page._prev; page._next = _head; _head._prev = page; page._prev = null; _head = page; } }
/// <summary>Writes the buffer to cache using pages</summary> /// <param name="buffer">source buffer</param> /// <param name="length">how many bytes to write</param> /// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> public override void Write(byte[] buffer, int length) { ValidateReadOnly(); long startAddress = _position; int bytesToWrite = length; int bufferOffset = 0; while (bytesToWrite > 0) { // page doesn't need to loadFromDisk if the whole page is dirty bool loadFromDisk = (bytesToWrite < _pageSize) || (startAddress % _pageSize != 0); CachedIoAdapter.Page page = GetPage(startAddress, loadFromDisk); page.EnsureEndAddress(GetLength()); int writtenBytes = page.Write(buffer, bufferOffset, startAddress, bytesToWrite); FlushIfHeaderBlockPage(page); MovePageToHead(page); bytesToWrite -= writtenBytes; startAddress += writtenBytes; bufferOffset += writtenBytes; } long endAddress = startAddress; _position = endAddress; _fileLength = Math.Max(endAddress, _fileLength); }
// Page page = (Page) _posPageMap.get(new Long(pos/PAGE_SIZE)); // return page; /// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> private void FlushAllPages() { CachedIoAdapter.Page node = _head; while (node != null) { FlushPage(node); node = node._next; } }
// _posPageMap.put(new Long(page.startPosition / PAGE_SIZE), page); /// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> private int IoRead(CachedIoAdapter.Page page) { int count = _io.Read(page._buffer); if (count > 0) { _filePointer = page._startAddress + count; } return(count); }
/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> private void FlushPage(CachedIoAdapter.Page page) { if (!page._dirty) { return; } IoSeek(page.StartAddress()); WritePageToDisk(page); return; }
/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> private CachedIoAdapter.Page GetPageFromCache(long pos) { CachedIoAdapter.Page page = _head; while (page != null) { if (page.Contains(pos)) { return(page); } page = page._next; } return(null); }
/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> private void WritePageToDisk(CachedIoAdapter.Page page) { ValidateReadOnly(); try { _io.Write(page._buffer, page.Size()); _filePointer = page.EndAddress(); page._dirty = false; } catch (Db4oIOException e) { _readOnly = true; throw; } }
private void InitCache() { _head = new CachedIoAdapter.Page(_pageSize); _head._prev = null; CachedIoAdapter.Page page = _head; CachedIoAdapter.Page next = _head; for (int i = 0; i < _pageCount - 1; ++i) { next = new CachedIoAdapter.Page(_pageSize); page._next = next; next._prev = page; page = next; } _tail = next; }
/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> private void GetPageFromDisk(CachedIoAdapter.Page page, long pos) { long startAddress = pos - pos % _pageSize; page.StartAddress(startAddress); IoSeek(page._startAddress); int count = IoRead(page); if (count > 0) { page.EndAddress(startAddress + count); } else { page.EndAddress(startAddress); } }
/// <summary>Reads the file into the buffer using pages from cache.</summary> /// <remarks> /// Reads the file into the buffer using pages from cache. If the next page /// is not cached it will be read from the file. /// </remarks> /// <param name="buffer">destination buffer</param> /// <param name="length">how many bytes to read</param> /// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> public override int Read(byte[] buffer, int length) { long startAddress = _position; int bytesToRead = length; int totalRead = 0; while (bytesToRead > 0) { CachedIoAdapter.Page page = GetPage(startAddress, true); int readBytes = page.Read(buffer, totalRead, startAddress, bytesToRead); MovePageToHead(page); if (readBytes <= 0) { break; } bytesToRead -= readBytes; startAddress += readBytes; totalRead += readBytes; } _position = startAddress; return(totalRead == 0 ? -1 : totalRead); }
/// <exception cref="Db4objects.Db4o.Ext.Db4oIOException"></exception> private CachedIoAdapter.Page GetPage(long startAddress, bool loadFromDisk) { CachedIoAdapter.Page page = GetPageFromCache(startAddress); if (page != null) { if (ContainsHeaderBlock(page)) { GetPageFromDisk(page, startAddress); } page.EnsureEndAddress(_fileLength); return(page); } // in case that page is not found in the cache page = GetFreePageFromCache(); if (loadFromDisk) { GetPageFromDisk(page, startAddress); } else { ResetPageAddress(page, startAddress); } return(page); }
private void MovePageToHead(CachedIoAdapter.Page page) { if (page == _head) { return; } if (page == _tail) { CachedIoAdapter.Page tempTail = _tail._prev; tempTail._next = null; _tail._next = _head; _tail._prev = null; _head._prev = page; _head = _tail; _tail = tempTail; } else { page._prev._next = page._next; page._next._prev = page._prev; page._next = _head; _head._prev = page; page._prev = null; _head = page; } }
private void InitCache() { _head = new CachedIoAdapter.Page(_pageSize); _head._prev = null; CachedIoAdapter.Page page = _head; CachedIoAdapter.Page next = _head; for (int i = 0; i < _pageCount - 1; ++i) { next = new CachedIoAdapter.Page(_pageSize); page._next = next; next._prev = page; page = next; } _tail = next; }
private void ResetPageAddress(CachedIoAdapter.Page page, long startAddress) { page.StartAddress(startAddress); page.EndAddress(startAddress + _pageSize); }
private bool ContainsHeaderBlock(CachedIoAdapter.Page page) { return(page.StartAddress() <= FileHeader1.HeaderLength); }