func (mvcc *MVCC) putInternal(key Key, timestamp hlc.Timestamp, value []byte, txnID string) error { keyMeta := &keyMetadata{} ok, err := GetI(mvcc.engine, key, keyMeta) if err != nil { return err } // In case the key metadata exists. if ok { // There is an uncommitted write intent and the current Put // operation does not come from the same transaction. // This should not happen since range should check the existing // write intent before executing any Put action at MVCC level. if len(keyMeta.TxnID) > 0 && (len(txnID) == 0 || keyMeta.TxnID != txnID) { return &writeIntentError{TxnID: keyMeta.TxnID} } if keyMeta.Timestamp.Less(timestamp) || (timestamp.Equal(keyMeta.Timestamp) && txnID == keyMeta.TxnID) { // Update key metadata. PutI(mvcc.engine, key, &keyMetadata{TxnID: txnID, Timestamp: timestamp}) } else { // In case we receive a Put request to update an old version, // it must be an error since raft should handle any client // retry from timeout. return &writeTimestampTooOldError{Timestamp: keyMeta.Timestamp} } } else { // In case the key metadata does not exist yet. // Create key metadata. PutI(mvcc.engine, key, &keyMetadata{TxnID: txnID, Timestamp: timestamp}) } // Save the value with the given version (Key + Timestamp). return mvcc.engine.Put(mvccEncodeKey(key, timestamp), value) }