public Stream Dequeue() { lock (_lockObject) { if (_metaData.HeadIndex == _metaData.TailIndex) // Head cought up with tail. Queue is empty. { return(null); // return null or Stream.Null? } // Delete previous index page if we are moving along to the next if (GetIndexPageIndex(_metaData.HeadIndex) != _headIndexPageIndex) { _indexPageFactory.DeletePage(_headIndexPageIndex); _headIndexPageIndex = GetIndexPageIndex(_metaData.HeadIndex); } // Get index item for head index var indexItem = GetIndexItem(_metaData.HeadIndex); // Delete previous data page if we are moving along to the next if (indexItem.DataPageIndex != _headDataPageIndex) { _dataPageFactory.DeletePage(_headDataPageIndex); _headDataPageIndex = indexItem.DataPageIndex; } // Get data page var dataPage = _dataPageFactory.GetPage(indexItem.DataPageIndex); // Get read stream MemoryStream memoryStream = new MemoryStream(); using (var readStream = dataPage.GetReadStream(indexItem.ItemOffset, indexItem.ItemLength)) { readStream.CopyTo(memoryStream, 4 * 1024); memoryStream.Position = 0; } _dataPageFactory.ReleasePage(dataPage.Index); // Update meta data if (_metaData.HeadIndex == long.MaxValue) { _metaData.HeadIndex = 0; } else { _metaData.HeadIndex++; } PersistMetaData(); return(memoryStream); } }
private void CommitBatch(ItemRange range) { var newHeadIndex = range.HeadIndex + range.ItemCount; long oldHeadIndex; lock (_lockObject) { // Update meta data oldHeadIndex = _metaData.HeadIndex; if (newHeadIndex > oldHeadIndex) { _metaData.HeadIndex = newHeadIndex; } PersistMetaData(); } if (newHeadIndex > oldHeadIndex) { var lastHeadIndex = GetPreviousIndex(oldHeadIndex); var lastWrittenIndex = GetPreviousIndex(newHeadIndex); var oldHeadIndexItem = GetIndexItem(lastHeadIndex); var lastWrittenIndexItem = GetIndexItem(lastWrittenIndex); for (var dataPageIndex = oldHeadIndexItem.DataPageIndex; dataPageIndex < lastWrittenIndexItem.DataPageIndex; dataPageIndex++) { _dataPageFactory.DeletePage(dataPageIndex); } for (var indexPageIndex = GetIndexPageIndex(lastHeadIndex); indexPageIndex < GetIndexPageIndex(lastWrittenIndex); indexPageIndex++) { _indexPageFactory.DeletePage(indexPageIndex); } } }