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; } }
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)); }