github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ccl/storageccl/revision_reader.go (about) 1 // Copyright 2016 The Cockroach Authors. 2 // 3 // Licensed as a CockroachDB Enterprise file under the Cockroach Community 4 // License (the "License"); you may not use this file except in compliance with 5 // the License. You may obtain a copy of the License at 6 // 7 // https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt 8 9 package storageccl 10 11 import ( 12 "context" 13 14 "github.com/cockroachdb/cockroach/pkg/kv" 15 "github.com/cockroachdb/cockroach/pkg/roachpb" 16 "github.com/cockroachdb/cockroach/pkg/storage" 17 "github.com/cockroachdb/cockroach/pkg/util/hlc" 18 ) 19 20 // VersionedValues is similar to roachpb.KeyValue except instead of just the 21 // value at one time, it contains all the retrieved revisions of the value for 22 // the key, with the value timestamps set accordingly. 23 type VersionedValues struct { 24 Key roachpb.Key 25 Values []roachpb.Value 26 } 27 28 // GetAllRevisions scans all keys between startKey and endKey getting all 29 // revisions between startTime and endTime. 30 // TODO(dt): if/when client gets a ScanRevisionsRequest or similar, use that. 31 func GetAllRevisions( 32 ctx context.Context, db *kv.DB, startKey, endKey roachpb.Key, startTime, endTime hlc.Timestamp, 33 ) ([]VersionedValues, error) { 34 // TODO(dt): version check. 35 header := roachpb.Header{Timestamp: endTime} 36 req := &roachpb.ExportRequest{ 37 RequestHeader: roachpb.RequestHeader{Key: startKey, EndKey: endKey}, 38 StartTime: startTime, 39 MVCCFilter: roachpb.MVCCFilter_All, 40 ReturnSST: true, 41 OmitChecksum: true, 42 } 43 resp, pErr := kv.SendWrappedWith(ctx, db.NonTransactionalSender(), header, req) 44 if pErr != nil { 45 return nil, pErr.GoError() 46 } 47 48 var res []VersionedValues 49 for _, file := range resp.(*roachpb.ExportResponse).Files { 50 sst := storage.MakeRocksDBSstFileReader() 51 defer sst.Close() 52 53 if err := sst.IngestExternalFile(file.SST); err != nil { 54 return nil, err 55 } 56 if err := sst.Iterate(startKey, endKey, func(kv storage.MVCCKeyValue) (bool, error) { 57 if len(res) == 0 || !res[len(res)-1].Key.Equal(kv.Key.Key) { 58 res = append(res, VersionedValues{Key: kv.Key.Key}) 59 } 60 res[len(res)-1].Values = append(res[len(res)-1].Values, roachpb.Value{Timestamp: kv.Key.Timestamp, RawBytes: kv.Value}) 61 return false, nil 62 }); err != nil { 63 return nil, err 64 } 65 } 66 return res, nil 67 }