github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/storage/row_counter.go (about) 1 // Copyright 2017 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package storage 12 13 import ( 14 "bytes" 15 16 "github.com/cockroachdb/cockroach/pkg/keys" 17 "github.com/cockroachdb/cockroach/pkg/roachpb" 18 ) 19 20 // RowCounter is a helper that counts how many distinct rows appear in the KVs 21 // that is is shown via `Count`. Note: the `DataSize` field of the BulkOpSummary 22 // is *not* populated by this and should be set separately. 23 type RowCounter struct { 24 roachpb.BulkOpSummary 25 prev roachpb.Key 26 } 27 28 // Count examines each key passed to it and increments the running count when it 29 // sees a key that belongs to a new row. 30 func (r *RowCounter) Count(key roachpb.Key) error { 31 // EnsureSafeSplitKey is usually used to avoid splitting a row across ranges, 32 // by returning the row's key prefix. 33 // We reuse it here to count "rows" by counting when it changes. 34 // Non-SQL keys are returned unchanged or may error -- we ignore them, since 35 // non-SQL keys are obviously thus not SQL rows. 36 // 37 // TODO(ajwerner): provide a separate mechanism to determine whether the key 38 // is a valid SQL key which explicitly indicates whether the key is valid as 39 // a split key independent of an error. See #43423. 40 row, err := keys.EnsureSafeSplitKey(key) 41 if err != nil || len(key) == len(row) { 42 // TODO(ajwerner): Determine which errors should be ignored and only 43 // ignore those. 44 return nil //nolint:returnerrcheck 45 } 46 47 // no change key prefix => no new row. 48 if bytes.Equal(row, r.prev) { 49 return nil 50 } 51 52 r.prev = append(r.prev[:0], row...) 53 54 rem, _, err := keys.DecodeTenantPrefix(row) 55 if err != nil { 56 return err 57 } 58 _, tableID, indexID, err := keys.DecodeTableIDIndexID(rem) 59 if err != nil { 60 return err 61 } 62 63 if r.EntryCounts == nil { 64 r.EntryCounts = make(map[uint64]int64) 65 } 66 r.EntryCounts[roachpb.BulkOpSummaryID(uint64(tableID), uint64(indexID))]++ 67 68 if indexID == 1 { 69 r.DeprecatedRows++ 70 } else { 71 r.DeprecatedIndexEntries++ 72 } 73 74 return nil 75 }