// getInternal implements the actual logic of get function. // The values of multiple versions for the given key should // be organized as follows: // ... // keyA : keyMetatata of keyA // keyA_Timestamp_n : value of version_n // keyA_Timestamp_n-1 : value of version_n-1 // ... // keyA_Timestamp_0 : value of version_0 // keyB : keyMetadata of keyB // ... func (mvcc *MVCC) getInternal(key Key, timestamp hlc.HLTimestamp, txnID string) ([]byte, hlc.HLTimestamp, string, error) { keyMetadata := &keyMetadata{} ok, err := GetI(mvcc.engine, key, keyMetadata) if err != nil || !ok { return nil, hlc.HLTimestamp{}, "", err } // If the read timestamp is greater than the latest one, we can just // fetch the value without a scan. if !timestamp.Less(keyMetadata.Timestamp) { if len(keyMetadata.TxnID) > 0 && (len(txnID) == 0 || keyMetadata.TxnID != txnID) { return nil, hlc.HLTimestamp{}, "", &writeIntentError{TxnID: keyMetadata.TxnID} } latestKey := mvccEncodeKey(key, keyMetadata.Timestamp) val, err := mvcc.engine.Get(latestKey) return val, keyMetadata.Timestamp, keyMetadata.TxnID, err } nextKey := mvccEncodeKey(key, timestamp) // We use the PrefixEndKey(key) as the upper bound for scan. // If there is no other version after nextKey, it won't return // the value of the next key. kvs, err := mvcc.engine.Scan(nextKey, PrefixEndKey(key), 1) if len(kvs) > 0 { _, ts := mvccDecodeKey(kvs[0].Key) return kvs[0].Value, ts, "", err } return nil, hlc.HLTimestamp{}, "", err }