github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/syndtr/goleveldb/manualtest/dbstress/key.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  
     7  	"github.com/insionng/yougam/libraries/syndtr/goleveldb/leveldb/errors"
     8  	"github.com/insionng/yougam/libraries/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  }