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  }