예제 #1
0
파일: tables.go 프로젝트: lovedboy/tidb
// 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
}
예제 #2
0
파일: tablecodec.go 프로젝트: anywhy/tidb
// 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
}
예제 #3
0
파일: snapshot.go 프로젝트: XuHuaiyu/tidb
// 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
	}
}
예제 #4
0
파일: mvcc_test.go 프로젝트: XuHuaiyu/tidb
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()
	}
}
예제 #5
0
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
}