+++ /dev/null
-package main
-
-import (
- "encoding/binary"
- "fmt"
-
- "github.com/syndtr/goleveldb/leveldb/errors"
- "github.com/syndtr/goleveldb/leveldb/storage"
-)
-
-type ErrIkeyCorrupted struct {
- Ikey []byte
- Reason string
-}
-
-func (e *ErrIkeyCorrupted) Error() string {
- return fmt.Sprintf("leveldb: iKey %q corrupted: %s", e.Ikey, e.Reason)
-}
-
-func newErrIkeyCorrupted(ikey []byte, reason string) error {
- return errors.NewErrCorrupted(storage.FileDesc{}, &ErrIkeyCorrupted{append([]byte{}, ikey...), reason})
-}
-
-type kType int
-
-func (kt kType) String() string {
- switch kt {
- case ktDel:
- return "d"
- case ktVal:
- return "v"
- }
- return "x"
-}
-
-// Value types encoded as the last component of internal keys.
-// Don't modify; this value are saved to disk.
-const (
- ktDel kType = iota
- ktVal
-)
-
-// ktSeek defines the kType that should be passed when constructing an
-// internal key for seeking to a particular sequence number (since we
-// sort sequence numbers in decreasing order and the value type is
-// embedded as the low 8 bits in the sequence number in internal keys,
-// we need to use the highest-numbered ValueType, not the lowest).
-const ktSeek = ktVal
-
-const (
- // Maximum value possible for sequence number; the 8-bits are
- // used by value type, so its can packed together in single
- // 64-bit integer.
- kMaxSeq uint64 = (uint64(1) << 56) - 1
- // Maximum value possible for packed sequence number and type.
- kMaxNum uint64 = (kMaxSeq << 8) | uint64(ktSeek)
-)
-
-// Maximum number encoded in bytes.
-var kMaxNumBytes = make([]byte, 8)
-
-func init() {
- binary.LittleEndian.PutUint64(kMaxNumBytes, kMaxNum)
-}
-
-type iKey []byte
-
-func newIkey(ukey []byte, seq uint64, kt kType) iKey {
- if seq > kMaxSeq {
- panic("leveldb: invalid sequence number")
- } else if kt > ktVal {
- panic("leveldb: invalid type")
- }
-
- ik := make(iKey, len(ukey)+8)
- copy(ik, ukey)
- binary.LittleEndian.PutUint64(ik[len(ukey):], (seq<<8)|uint64(kt))
- return ik
-}
-
-func parseIkey(ik []byte) (ukey []byte, seq uint64, kt kType, err error) {
- if len(ik) < 8 {
- return nil, 0, 0, newErrIkeyCorrupted(ik, "invalid length")
- }
- num := binary.LittleEndian.Uint64(ik[len(ik)-8:])
- seq, kt = uint64(num>>8), kType(num&0xff)
- if kt > ktVal {
- return nil, 0, 0, newErrIkeyCorrupted(ik, "invalid type")
- }
- ukey = ik[:len(ik)-8]
- return
-}
-
-func validIkey(ik []byte) bool {
- _, _, _, err := parseIkey(ik)
- return err == nil
-}
-
-func (ik iKey) assert() {
- if ik == nil {
- panic("leveldb: nil iKey")
- }
- if len(ik) < 8 {
- panic(fmt.Sprintf("leveldb: iKey %q, len=%d: invalid length", ik, len(ik)))
- }
-}
-
-func (ik iKey) ukey() []byte {
- ik.assert()
- return ik[:len(ik)-8]
-}
-
-func (ik iKey) num() uint64 {
- ik.assert()
- return binary.LittleEndian.Uint64(ik[len(ik)-8:])
-}
-
-func (ik iKey) parseNum() (seq uint64, kt kType) {
- num := ik.num()
- seq, kt = uint64(num>>8), kType(num&0xff)
- if kt > ktVal {
- panic(fmt.Sprintf("leveldb: iKey %q, len=%d: invalid type %#x", ik, len(ik), kt))
- }
- return
-}
-
-func (ik iKey) String() string {
- if ik == nil {
- return "<nil>"
- }
-
- if ukey, seq, kt, err := parseIkey(ik); err == nil {
- return fmt.Sprintf("%x,%s%d", ukey, kt, seq)
- } else {
- return "<invalid>"
- }
-}