Beispiel #1
0
        public Block(Slice data)
        {
            if (data.Length < sizeof(uint))
            {
                throw new Exception("bad block contents");
            }

            // restart points are recorded at the end of the buffer.
            uint numRestarts   = Coding.DecodeFixed32(data.NewSlice(data.Length - sizeof(uint), sizeof(uint)));
            uint restartOffset = data.Length - (1 + numRestarts) * sizeof(uint);

            // we don't really care for these except the first, but we'll parse them.
            var restartPoints = new uint[numRestarts];

            for (uint i = 0; i < numRestarts; ++i)
            {
                var offset = restartOffset + (i * sizeof(uint));
                restartPoints[i] = Coding.DecodeFixed32(data.NewSlice(offset, sizeof(uint)));
            }

            // block data is the remaining data.
            var blockData = data.NewSlice(0, restartOffset);

            // parse this block.
            var key   = new InternalKey();
            var value = blockData.NewSlice(0, 0);

            uint m_current = restartPoints[0];

            while (m_current < blockData.Length)
            {
                Slice?p = blockData.NewSlice(m_current);

                // Decode next entry
                p = DecodeEntry(p, out uint shared, out uint non_shared, out uint value_length);
                if (p == null || key.Length < shared)
                {
                    throw new Exception("bad entry in block");
                }
                else
                {
                    key.Resize(shared);
                    key.Append(p.NewSlice(0, non_shared));

                    value.Update(p.Offset + non_shared, value_length);

                    // don't add deleted keys to the dictionary.
                    var parsedKey = new Key(key.Slice(0, key.Length));
                    if (parsedKey.Type == KeyType.kTypeValue)
                    {
                        m_keys.Add(parsedKey.UserKey);
                        m_values.Add(value.ToArray());
                    }
                }

                m_current = value.Offset + value.Length;
            }
        }
Beispiel #2
0
        public static Footer DecodeFrom(Slice slice)
        {
            uint startOffset = slice.Offset;
            uint startLength = slice.Length;

            uint  magic_lo = Coding.DecodeFixed32(slice.NewSlice(kEncodedLength - 8, 4));
            uint  magic_hi = Coding.DecodeFixed32(slice.NewSlice(kEncodedLength - 4, 4));
            ulong magic    = (unchecked ((ulong)magic_hi) << 32) | unchecked ((ulong)magic_lo);

            if (magic != kTableMagicNumber)
            {
                throw new Exception("not an sstable (bad magic number)");
            }

            var metaIndexHandle = BlockHandle.DecodeFrom(slice);
            var indexHandle     = BlockHandle.DecodeFrom(slice);

            slice.Update(startOffset + kEncodedLength, startLength - kEncodedLength);
            return(new Footer(metaIndexHandle, indexHandle));
        }