// DecodeRecordKey decodes the key and gets the tableID, handle and columnID. func DecodeRecordKey(key kv.Key) (tableID int64, handle int64, columnID int64, err error) { k := key if !key.HasPrefix(TablePrefix) { return 0, 0, 0, errors.Errorf("invalid record key - %q", k) } key = key[len(TablePrefix):] key, tableID, err = codec.DecodeInt(key) if err != nil { return 0, 0, 0, errors.Trace(err) } if !key.HasPrefix(recordPrefixSep) { return 0, 0, 0, errors.Errorf("invalid record key - %q", k) } key = key[len(recordPrefixSep):] key, handle, err = codec.DecodeInt(key) if err != nil { return 0, 0, 0, errors.Trace(err) } if len(key) == 0 { return } key, columnID, err = codec.DecodeInt(key) if err != nil { return 0, 0, 0, errors.Trace(err) } return }
// DecodeRowKey decodes the key and gets the handle. func DecodeRowKey(key kv.Key) (handle int64, err error) { k := key if !key.HasPrefix(tablePrefix) { return 0, errInvalidRecordKey.Gen("invalid record key - %q", k) } key = key[len(tablePrefix):] // Table ID is not needed. key, _, err = codec.DecodeInt(key) if err != nil { return 0, errors.Trace(err) } if !key.HasPrefix(recordPrefixSep) { return 0, errInvalidRecordKey.Gen("invalid record key - %q", k) } key = key[len(recordPrefixSep):] key, handle, err = codec.DecodeInt(key) if err != nil { return 0, errors.Trace(err) } return }
// mvccSeek seeks for the first key in db which has a k >= key and a version <= // snapshot's version, returns kv.ErrNotExist if such key is not found. If exact // is true, only k == key can be returned. func (s *dbSnapshot) mvccSeek(key kv.Key, exact bool) (kv.Key, []byte, error) { // Key layout: // ... // Key_verMax -- (1) // ... // Key_ver+1 -- (2) // Key_ver -- (3) // Key_ver-1 -- (4) // ... // Key_0 -- (5) // NextKey_verMax -- (6) // ... // NextKey_ver+1 -- (7) // NextKey_ver -- (8) // NextKey_ver-1 -- (9) // ... // NextKey_0 -- (10) // ... // EOF for { mvccKey := MvccEncodeVersionKey(key, s.version) mvccK, v, err := s.store.Seek([]byte(mvccKey), s.version.Ver) // search for [3...EOF) if err != nil { if terror.ErrorEqual(err, engine.ErrNotFound) { // EOF return nil, nil, errors.Trace(kv.ErrNotExist) } return nil, nil, errors.Trace(err) } k, ver, err := MvccDecode(mvccK) if err != nil { return nil, nil, errors.Trace(err) } // quick test for exact mode if exact { if key.Cmp(k) != 0 || isTombstone(v) { return nil, nil, errors.Trace(kv.ErrNotExist) } return k, v, nil } if ver.Ver > s.version.Ver { // currently on [6...7] key = k // search for [8...EOF) next loop continue } // currently on [3...5] or [8...10] if isTombstone(v) { key = k.Next() // search for (5...EOF) or (10..EOF) next loop continue } // target found return k, v, nil } }
func (t *testMvccSuite) scanRawEngine(c *C, f func([]byte, []byte)) { // scan raw db var k kv.Key var v []byte for { var err error k, v, err = t.s.(*dbStore).db.Seek(k) if err != nil { break } f(k, v) k = k.Next() } }
func count(db engine.DB) int { var k kv.Key totalCnt := 0 for { var err error k, _, err = db.Seek(k) if err != nil { break } k = k.Next() totalCnt++ } return totalCnt }