コード例 #1
0
        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)
            });
        }
コード例 #2
0
        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);
        }