mirror of
https://github.com/talent-plan/tinykv.git
synced 2025-02-14 22:00:08 +08:00
* add coprocessor support Signed-off-by: Connor1996 <zbk602423539@gmail.com> Co-authored-by: Yiding Cui <winoros@gmail.com>
126 lines
3.8 KiB
Go
126 lines
3.8 KiB
Go
package mvcc
|
|
|
|
import (
|
|
"encoding/binary"
|
|
|
|
"github.com/pingcap-incubator/tinykv/kv/storage"
|
|
"github.com/pingcap-incubator/tinykv/kv/util/codec"
|
|
"github.com/pingcap-incubator/tinykv/proto/pkg/kvrpcpb"
|
|
"github.com/pingcap-incubator/tinykv/scheduler/pkg/tsoutil"
|
|
)
|
|
|
|
// KeyError is a wrapper type so we can implement the `error` interface.
|
|
type KeyError struct {
|
|
kvrpcpb.KeyError
|
|
}
|
|
|
|
func (ke *KeyError) Error() string {
|
|
return ke.String()
|
|
}
|
|
|
|
// MvccTxn groups together writes as part of a single transaction. It also provides an abstraction over low-level
|
|
// storage, lowering the concepts of timestamps, writes, and locks into plain keys and values.
|
|
type MvccTxn struct {
|
|
StartTS uint64
|
|
Reader storage.StorageReader
|
|
writes []storage.Modify
|
|
}
|
|
|
|
func NewMvccTxn(reader storage.StorageReader, startTs uint64) *MvccTxn {
|
|
return &MvccTxn{
|
|
Reader: reader,
|
|
StartTS: startTs,
|
|
}
|
|
}
|
|
|
|
// Writes returns all changes added to this transaction.
|
|
func (txn *MvccTxn) Writes() []storage.Modify {
|
|
return txn.writes
|
|
}
|
|
|
|
// PutWrite records a write at key and ts.
|
|
func (txn *MvccTxn) PutWrite(key []byte, ts uint64, write *Write) {
|
|
// Your Code Here (4A).
|
|
}
|
|
|
|
// GetLock returns a lock if key is locked. It will return (nil, nil) if there is no lock on key, and (nil, err)
|
|
// if an error occurs during lookup.
|
|
func (txn *MvccTxn) GetLock(key []byte) (*Lock, error) {
|
|
// Your Code Here (4A).
|
|
return nil, nil
|
|
}
|
|
|
|
// PutLock adds a key/lock to this transaction.
|
|
func (txn *MvccTxn) PutLock(key []byte, lock *Lock) {
|
|
// Your Code Here (4A).
|
|
}
|
|
|
|
// DeleteLock adds a delete lock to this transaction.
|
|
func (txn *MvccTxn) DeleteLock(key []byte) {
|
|
// Your Code Here (4A).
|
|
}
|
|
|
|
// GetValue finds the value for key, valid at the start timestamp of this transaction.
|
|
// I.e., the most recent value committed before the start of this transaction.
|
|
func (txn *MvccTxn) GetValue(key []byte) ([]byte, error) {
|
|
// Your Code Here (4A).
|
|
return nil, nil
|
|
}
|
|
|
|
// PutValue adds a key/value write to this transaction.
|
|
func (txn *MvccTxn) PutValue(key []byte, value []byte) {
|
|
// Your Code Here (4A).
|
|
}
|
|
|
|
// DeleteValue removes a key/value pair in this transaction.
|
|
func (txn *MvccTxn) DeleteValue(key []byte) {
|
|
// Your Code Here (4A).
|
|
}
|
|
|
|
// CurrentWrite searches for a write with this transaction's start timestamp. It returns a Write from the DB and that
|
|
// write's commit timestamp, or an error.
|
|
func (txn *MvccTxn) CurrentWrite(key []byte) (*Write, uint64, error) {
|
|
// Your Code Here (4A).
|
|
return nil, 0, nil
|
|
}
|
|
|
|
// MostRecentWrite finds the most recent write with the given key. It returns a Write from the DB and that
|
|
// write's commit timestamp, or an error.
|
|
func (txn *MvccTxn) MostRecentWrite(key []byte) (*Write, uint64, error) {
|
|
// Your Code Here (4A).
|
|
return nil, 0, nil
|
|
}
|
|
|
|
// EncodeKey encodes a user key and appends an encoded timestamp to a key. Keys and timestamps are encoded so that
|
|
// timestamped keys are sorted first by key (ascending), then by timestamp (descending). The encoding is based on
|
|
// https://github.com/facebook/mysql-5.6/wiki/MyRocks-record-format#memcomparable-format.
|
|
func EncodeKey(key []byte, ts uint64) []byte {
|
|
encodedKey := codec.EncodeBytes(key)
|
|
newKey := append(encodedKey, make([]byte, 8)...)
|
|
binary.BigEndian.PutUint64(newKey[len(encodedKey):], ^ts)
|
|
return newKey
|
|
}
|
|
|
|
// DecodeUserKey takes a key + timestamp and returns the key part.
|
|
func DecodeUserKey(key []byte) []byte {
|
|
_, userKey, err := codec.DecodeBytes(key)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return userKey
|
|
}
|
|
|
|
// decodeTimestamp takes a key + timestamp and returns the timestamp part.
|
|
func decodeTimestamp(key []byte) uint64 {
|
|
left, _, err := codec.DecodeBytes(key)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return ^binary.BigEndian.Uint64(left)
|
|
}
|
|
|
|
// PhysicalTime returns the physical time part of the timestamp.
|
|
func PhysicalTime(ts uint64) uint64 {
|
|
return ts >> tsoutil.PhysicalShiftBits
|
|
}
|