Example #1
0
 internal SSTable(Stream stream, IBlockCache?cache, PlaneDBOptions options)
 {
     this.stream = stream;
     comparer    = options.Comparer;
     reader      = OpenReaderStream(cache, options);
     index       = new Lazy <Index>(() => new Index(reader), LazyThreadSafetyMode.ExecutionAndPublication);
 }
Example #2
0
 internal SSTableBuilder(Stream stream, PlaneDBOptions options)
 {
     writer     = new BlockWriteOnceStream(stream, options.BlockTransformer);
     comparer   = options.Comparer;
     fullySync  = options.MaxJournalActions < 0;
     dictionary = new SortedList <byte[], byte[]?>(comparer);
 }
Example #3
0
        /// <summary>
        ///   Configure the byte comparer implementation
        /// </summary>
        /// <param name="comparer">Comparer to use</param>
        /// <returns>New options with comparer configured</returns>
        /// <seealso cref="Comparer" />
        /// <remarks>The block comparer must be deterministic and SHOULD sort byte arrays lexically</remarks>
        public PlaneDBOptions WithComparer(IByteArrayComparer comparer)
        {
            var rv = Clone();

            rv.Comparer = comparer;
            return(rv);
        }
Example #4
0
        private static IEnumerable <KeyValuePair <byte[], byte[]?> > EnumerateSortedTables(
            IEnumerable <KeyValuePair <byte[], byte[]?> >[] sequence, IByteArrayComparer comparer)
        {
            // ReSharper disable once ConvertIfStatementToSwitchStatement
            if (sequence.Length == 0)
            {
                return(Array.Empty <KeyValuePair <byte[], byte[]?> >());
            }

            if (sequence.Length == 1)
            {
                return(sequence[0]);
            }

            if (sequence.Length == 2)
            {
                return(MergeTwoSortedEnumerables(sequence[0], sequence[1], comparer));
            }

            var mid         = (int)Math.Ceiling((double)sequence.Length / 2);
            var leftTables  = sequence.AsSpan(0, mid).ToArray();
            var rightTables = sequence.AsSpan(mid).ToArray();

            return(MergeTwoSortedEnumerables(EnumerateSortedTables(leftTables, comparer),
                                             EnumerateSortedTables(rightTables, comparer),
                                             comparer));
        }
Example #5
0
            internal Enumerator(IReadOnlyTable[] tables, bool readValues, IByteArrayComparer comparer)
            {
                this.tables     = tables;
                this.readValues = readValues;
                this.comparer   = comparer;
                foreach (var r in tables)
                {
                    if (r is SSTable t)
                    {
                        t.AddRef();
                    }
                }

                enumerator = CreateInternal();
            }
Example #6
0
        private static IEnumerable <KeyValuePair <byte[], byte[]?> > MergeTwoSortedEnumerables(
            IEnumerable <KeyValuePair <byte[], byte[]?> > leftIter, IEnumerable <KeyValuePair <byte[], byte[]?> > rightIter,
            IByteArrayComparer comparer)
        {
            using (var leftEnum = leftIter.GetEnumerator())
                using (var rightEnum = rightIter.GetEnumerator()) {
                    if (!rightEnum.MoveNext())
                    {
                        while (leftEnum.MoveNext())
                        {
                            yield return(leftEnum.Current);
                        }

                        yield break;
                    }

                    if (!leftEnum.MoveNext())
                    {
                        while (rightEnum.MoveNext())
                        {
                            yield return(rightEnum.Current);
                        }

                        yield break;
                    }

                    for (;;)
                    {
                        var l  = leftEnum.Current;
                        var r  = rightEnum.Current;
                        var rv = comparer.Compare(l.Key, r.Key);
                        if (rv == 0)
                        {
                            yield return(l);

                            // Skip over current r
                            if (!rightEnum.MoveNext())
                            {
                                while (leftEnum.MoveNext())
                                {
                                    yield return(leftEnum.Current);
                                }

                                yield break;
                            }

                            if (leftEnum.MoveNext())
                            {
                                continue;
                            }

                            yield return(r);

                            while (rightEnum.MoveNext())
                            {
                                yield return(rightEnum.Current);
                            }

                            yield break;
                        }

                        if (rv < 0)
                        {
                            yield return(l);

                            if (leftEnum.MoveNext())
                            {
                                continue;
                            }

                            yield return(r);

                            while (rightEnum.MoveNext())
                            {
                                yield return(rightEnum.Current);
                            }

                            yield break;
                        }

                        yield return(r);

                        if (rightEnum.MoveNext())
                        {
                            continue;
                        }

                        yield return(l);

                        while (leftEnum.MoveNext())
                        {
                            yield return(leftEnum.Current);
                        }

                        yield break;
                    }
                }
        }