OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / syndtr / goleveldb / manualtest / dbstress / key.go
1 package main
2
3 import (
4         "encoding/binary"
5         "fmt"
6
7         "github.com/syndtr/goleveldb/leveldb/errors"
8         "github.com/syndtr/goleveldb/leveldb/storage"
9 )
10
11 type ErrIkeyCorrupted struct {
12         Ikey   []byte
13         Reason string
14 }
15
16 func (e *ErrIkeyCorrupted) Error() string {
17         return fmt.Sprintf("leveldb: iKey %q corrupted: %s", e.Ikey, e.Reason)
18 }
19
20 func newErrIkeyCorrupted(ikey []byte, reason string) error {
21         return errors.NewErrCorrupted(storage.FileDesc{}, &ErrIkeyCorrupted{append([]byte{}, ikey...), reason})
22 }
23
24 type kType int
25
26 func (kt kType) String() string {
27         switch kt {
28         case ktDel:
29                 return "d"
30         case ktVal:
31                 return "v"
32         }
33         return "x"
34 }
35
36 // Value types encoded as the last component of internal keys.
37 // Don't modify; this value are saved to disk.
38 const (
39         ktDel kType = iota
40         ktVal
41 )
42
43 // ktSeek defines the kType that should be passed when constructing an
44 // internal key for seeking to a particular sequence number (since we
45 // sort sequence numbers in decreasing order and the value type is
46 // embedded as the low 8 bits in the sequence number in internal keys,
47 // we need to use the highest-numbered ValueType, not the lowest).
48 const ktSeek = ktVal
49
50 const (
51         // Maximum value possible for sequence number; the 8-bits are
52         // used by value type, so its can packed together in single
53         // 64-bit integer.
54         kMaxSeq uint64 = (uint64(1) << 56) - 1
55         // Maximum value possible for packed sequence number and type.
56         kMaxNum uint64 = (kMaxSeq << 8) | uint64(ktSeek)
57 )
58
59 // Maximum number encoded in bytes.
60 var kMaxNumBytes = make([]byte, 8)
61
62 func init() {
63         binary.LittleEndian.PutUint64(kMaxNumBytes, kMaxNum)
64 }
65
66 type iKey []byte
67
68 func newIkey(ukey []byte, seq uint64, kt kType) iKey {
69         if seq > kMaxSeq {
70                 panic("leveldb: invalid sequence number")
71         } else if kt > ktVal {
72                 panic("leveldb: invalid type")
73         }
74
75         ik := make(iKey, len(ukey)+8)
76         copy(ik, ukey)
77         binary.LittleEndian.PutUint64(ik[len(ukey):], (seq<<8)|uint64(kt))
78         return ik
79 }
80
81 func parseIkey(ik []byte) (ukey []byte, seq uint64, kt kType, err error) {
82         if len(ik) < 8 {
83                 return nil, 0, 0, newErrIkeyCorrupted(ik, "invalid length")
84         }
85         num := binary.LittleEndian.Uint64(ik[len(ik)-8:])
86         seq, kt = uint64(num>>8), kType(num&0xff)
87         if kt > ktVal {
88                 return nil, 0, 0, newErrIkeyCorrupted(ik, "invalid type")
89         }
90         ukey = ik[:len(ik)-8]
91         return
92 }
93
94 func validIkey(ik []byte) bool {
95         _, _, _, err := parseIkey(ik)
96         return err == nil
97 }
98
99 func (ik iKey) assert() {
100         if ik == nil {
101                 panic("leveldb: nil iKey")
102         }
103         if len(ik) < 8 {
104                 panic(fmt.Sprintf("leveldb: iKey %q, len=%d: invalid length", ik, len(ik)))
105         }
106 }
107
108 func (ik iKey) ukey() []byte {
109         ik.assert()
110         return ik[:len(ik)-8]
111 }
112
113 func (ik iKey) num() uint64 {
114         ik.assert()
115         return binary.LittleEndian.Uint64(ik[len(ik)-8:])
116 }
117
118 func (ik iKey) parseNum() (seq uint64, kt kType) {
119         num := ik.num()
120         seq, kt = uint64(num>>8), kType(num&0xff)
121         if kt > ktVal {
122                 panic(fmt.Sprintf("leveldb: iKey %q, len=%d: invalid type %#x", ik, len(ik), kt))
123         }
124         return
125 }
126
127 func (ik iKey) String() string {
128         if ik == nil {
129                 return "<nil>"
130         }
131
132         if ukey, seq, kt, err := parseIkey(ik); err == nil {
133                 return fmt.Sprintf("%x,%s%d", ukey, kt, seq)
134         } else {
135                 return "<invalid>"
136         }
137 }