// GC implements the MVCCStore interface
GC implements the MVCCStore interface
// GC implements the MVCCStore interface
func (mvcc *MVCCRocksDB) GC(startKey, endKey []byte, safePoint uint64) error {
	mvcc.mu.Lock()
	defer mvcc.mu.Unlock()
	iter, currKey, err := newScanIterator(mvcc.db, startKey, endKey)
	defer iter.Close()
	if err != nil {
		return errors.Trace(err)
	}
	batch := gorocksdb.NewWriteBatch()
	for iter.Valid() {
		lockDec := lockDecoder{expectKey: currKey}
		ok, err := lockDec.Decode(iter)
		if err != nil {
			return errors.Trace(err)
		}
		if ok && lockDec.lock.startTS <= safePoint {
			return errors.Errorf(
				"key %+q has lock with startTs %v which is under safePoint %v",
				currKey,
				lockDec.lock.startTS,
				safePoint)
		}
		keepNext := true
		dec := valueDecoder{expectKey: currKey}
		for iter.Valid() {
			ok, err := dec.Decode(iter)
			if err != nil {
				return errors.Trace(err)
			}
			if !ok {
				currKey, _, err = mvccDecode(iter.Key().Data())
				if err != nil {
					return errors.Trace(err)
				}
				break
			}
			if dec.value.commitTS > safePoint {
				continue
			}
			if dec.value.valueType == typePut || dec.value.valueType == typeDelete {
				if !keepNext || dec.value.valueType == typeDelete {
					batch.Delete(mvccEncode(currKey, dec.value.commitTS))
				}
				keepNext = false
			} else {
				batch.Delete(mvccEncode(currKey, dec.value.commitTS))
			}
		}
	}
	return mvcc.db.Write(gorocksdb.NewDefaultWriteOptions(), batch)
}
func ( mvcc * MVCCRocksDB ) GC ( startKey , endKey [ ] byte , safePoint uint64 ) error { mvcc . mu . Lock ( ) defer mvcc . mu . Unlock ( ) iter , currKey , err := newScanIterator ( mvcc . db , startKey , endKey ) defer iter . Close ( ) if err != nil { return errors . Trace ( err ) } batch := gorocksdb . NewWriteBatch ( ) for iter . Valid ( ) { lockDec := lockDecoder { expectKey : currKey } ok , err := lockDec . Decode ( iter ) if err != nil { return errors . Trace ( err ) } if ok && lockDec . lock . startTS <= safePoint { return errors . Errorf ( " " , currKey , lockDec . lock . startTS , safePoint ) } keepNext := true dec := valueDecoder { expectKey : currKey } for iter . Valid ( ) { ok , err := dec . Decode ( iter ) if err != nil { return errors . Trace ( err ) } if ! ok { currKey , _ , err = mvccDecode ( iter . Key ( ) . Data ( ) ) if err != nil { return errors . Trace ( err ) } break } if dec . value . commitTS > safePoint { continue } if dec . value . valueType == typePut || dec . value . valueType == typeDelete { if ! keepNext || dec . value . valueType == typeDelete { batch . Delete ( mvccEncode ( currKey , dec . value . commitTS ) ) } keepNext = false } else { batch . Delete ( mvccEncode ( currKey , dec . value . commitTS ) ) } } } return mvcc . db . Write ( gorocksdb . NewDefaultWriteOptions ( ) , batch ) }
GC implements the MVCCStore interface
GC implements the MVCCStore interface
// Mock TiKV usually doesn't need to process large amount of data. So write it in a single batch. // Go to the next key // Keep the latest version if it's `typePut` // Delete all other types