internal FileMetadata WriteLevel0Table(MemCache memCache, FileInfo tableFileInfo) { using FileStream fileStream = File.Create(tableFileInfo.FullName); var creator = new TableCreator(fileStream); byte[] smallestKey = null; byte[] largestKey = null; foreach (KeyValuePair <byte[], MemCache.ResultCacheEntry> entry in memCache._resultCache.OrderBy(kvp => kvp.Key, new BytewiseComparator()).ThenBy(kvp => kvp.Value.Sequence)) { if (entry.Value.ResultState != ResultState.Exist && entry.Value.ResultState != ResultState.Deleted) { continue; } byte[] opAndSeq = BitConverter.GetBytes((ulong)entry.Value.Sequence << 8); opAndSeq[0] = (byte)(entry.Value.ResultState == ResultState.Exist ? 1 : 0); byte[] key = entry.Key.Concat(opAndSeq).ToArray(); byte[] data = entry.Value.Data; smallestKey ??= key; largestKey = key; //if (Log.IsDebugEnabled) //{ // if (entry.Value.ResultState == ResultState.Deleted) // Log.Warn($"Key:{key.ToHexString()} {entry.Value.Sequence}, {entry.Value.ResultState == ResultState.Exist}, size:{entry.Value.Data?.Length ?? 0}"); // else //Log.Debug($"Key: {entry.Key.ToHexString()} FullKey:{key.ToHexString()} Seq: {entry.Value.Sequence}, Exist: {entry.Value.ResultState == ResultState.Exist}"); //} creator.Add(key, data); } creator.Finish(); fileStream.Flush(); fileStream.Close(); tableFileInfo.Refresh(); Log.Debug($"Size distinct:{memCache._resultCache.Distinct().Count()}"); Log.Debug($"Wrote {memCache._resultCache.Count} values to {tableFileInfo.Name}"); return(new FileMetadata { FileNumber = 0, // Set in calling method FileSize = (ulong)tableFileInfo.Length, SmallestKey = smallestKey, LargestKey = largestKey, Table = new Table(tableFileInfo) }); }
private FileMetadata WriteMergedTable(Version version, MergeEnumerator mergeEnumerator, ref int count) { var newFileMeta = new FileMetadata { FileNumber = version.GetNewFileNumber() }; var newFileInfo = new FileInfo(GetTableFileName(newFileMeta.FileNumber)); using FileStream newFileStream = newFileInfo.Create(); var creator = new TableCreator(newFileStream); byte[] smallestKey = null; byte[] largestKey = null; ReadOnlyMemory <byte> prevKey = null; while (mergeEnumerator.MoveNext()) { BlockEntry entry = mergeEnumerator.Current; count++; ReadOnlyMemory <byte> key = entry.Key; if (prevKey.Length != 0) { if (prevKey.Span.UserKey().SequenceEqual(key.Span.UserKey())) { Log.Warn($"Duplicate keys - Prev Key: {prevKey.ToHexString()}, Key: {key.ToHexString()}"); continue; } } prevKey = key; creator.Add(key.Span, entry.Data.Span); smallestKey ??= key.ToArray(); largestKey = key.ToArray(); if (creator.CurrentSize > Options.MaxTableFileSize) { break; } } creator.Finish(); newFileMeta.SmallestKey = smallestKey; newFileMeta.LargestKey = largestKey; newFileInfo.Refresh(); newFileMeta.FileSize = (ulong)newFileInfo.Length; return(newFileMeta); }