public void Finish() { Flush(); _closed = true; BlockHandle filterBlockHandle = null; //write filter block if (_filterBuilder != null) filterBlockHandle = _filterBuilder.Finish(_dataStream); // write metadata block var metaIndexBlock = new BlockBuilder(_dataStream, _storageState, _storageState.InternalKeyComparator, _storageState.Options.BlockRestartInterval); if (filterBlockHandle != null) { metaIndexBlock.Add(("filter." + _storageState.Options.FilterPolicy.Name), filterBlockHandle.AsStream()); } var metadIndexBlockHandle = WriteBlock(metaIndexBlock); // write index block if (_pendingIndexEntry) { var newKey = _storageState.InternalKeyComparator.FindShortestSuccessor(_lastKey, ref _scratchBuffer); _indexBlock.Add(newKey, _pendingHandle.AsStream()); _pendingIndexEntry = false; } var indexBlockSize = _indexBlock.Finish(); _indexBlock.Stream.WriteByte(0);//write type, uncompressed _indexBlock.Stream.WriteInt32(Crc.Mask(_indexBlock.Stream.WriteCrc)); _indexBlock.Stream.Position = _originalIndexStreamPosition; var indexBlockHandler = new BlockHandle { Position = _dataStream.Position, Count = indexBlockSize }; _indexBlock.Stream.Stream.CopyTo(_dataStream); // write footer var footer = new Footer { IndexHandle = indexBlockHandler, MetaIndexHandle = metadIndexBlockHandle }; footer.EncodeTo(_dataStream); }
public Table(StorageState storageState, FileData fileData) { _storageState = storageState; try { _fileData = fileData; if (_storageState.Options.MaxBlockCacheSizePerTableFile > 0) { _blockCache = new LruCache<BlockHandle, Block>(_storageState.Options.MaxBlockCacheSizePerTableFile); } if (fileData.Size < Footer.EncodedLength) throw new CorruptedDataException("File is too short to be an sstable"); var footer = new Footer(); using (var accessor = fileData.File.CreateAccessor(fileData.Size - Footer.EncodedLength, Footer.EncodedLength)) { footer.DecodeFrom(accessor); } var readOptions = new ReadOptions { VerifyChecksums = _storageState.Options.ParanoidChecks }; _indexBlock = new Block(_storageState.Options, readOptions, footer.IndexHandle, fileData); _indexBlock.IncrementUsage(); if (_storageState.Options.FilterPolicy == null) return; // we don't need any metadata using (var metaBlock = new Block(_storageState.Options, readOptions, footer.MetaIndexHandle, fileData)) using (var iterator = metaBlock.CreateIterator(CaseInsensitiveComparator.Default)) { var filterName = ("filter." + _storageState.Options.FilterPolicy.Name); iterator.Seek(filterName); if (iterator.IsValid && CaseInsensitiveComparator.Default.Compare(filterName, iterator.Key) == 0) { var handle = new BlockHandle(); using (var stream = iterator.CreateValueStream()) { handle.DecodeFrom(stream); } var filterAccessor = _fileData.File.CreateAccessor(handle.Position, handle.Count); try { _filter = _storageState.Options.FilterPolicy.CreateFilter(filterAccessor); } catch (Exception) { if (_filter == null) filterAccessor.Dispose(); else _filter.Dispose(); throw; } } } } catch (Exception) { Dispose(); throw; } }