Skip to content

Commit ee6fff3

Browse files
committed
vecindex: improve Index.Format method
Now that we have a non-transactional Store.TryGetPartition method, use it in Index.Format. The Format method is used in testing/debugging, and doesn't need to be transactional. Removing its dependence on GetPartition will eventually allow us to remove that method entirely. Also begin showing partition state if it is not Ready. This will be needed as we begin using other states. Update all the places where we create partition metadata to set the state so that Format shows expected results. Epic: CRDB-42943 Release note: None
1 parent 5af35e3 commit ee6fff3

File tree

14 files changed

+255
-107
lines changed

14 files changed

+255
-107
lines changed

pkg/sql/vecindex/cspann/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ go_library(
3737
"//pkg/util/num32",
3838
"//pkg/util/stop",
3939
"//pkg/util/syncutil",
40+
"//pkg/util/timeutil",
4041
"//pkg/util/vector",
4142
"@com_github_cockroachdb_crlib//crtime",
4243
"@com_github_cockroachdb_errors//:errors",

pkg/sql/vecindex/cspann/commontest/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ go_library(
1414
"//pkg/sql/vecindex/cspann/testutils",
1515
"//pkg/sql/vecindex/cspann/workspace",
1616
"//pkg/util/num32",
17-
"//pkg/util/timeutil",
1817
"//pkg/util/vector",
1918
"@com_github_cockroachdb_errors//:errors",
2019
"@com_github_stretchr_testify//require",

pkg/sql/vecindex/cspann/commontest/storetests.go

Lines changed: 25 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"github.com/cockroachdb/cockroach/pkg/sql/vecindex/cspann/testutils"
1515
"github.com/cockroachdb/cockroach/pkg/sql/vecindex/cspann/workspace"
1616
"github.com/cockroachdb/cockroach/pkg/util/num32"
17-
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
1817
"github.com/cockroachdb/cockroach/pkg/util/vector"
1918
"github.com/cockroachdb/errors"
2019
"github.com/stretchr/testify/suite"
@@ -229,7 +228,10 @@ func (suite *StoreTestSuite) TestNonRootPartition() {
229228
childKeys := []cspann.ChildKey{partitionKey1, partitionKey2}
230229
valueBytes := []cspann.ValueBytes{valueBytes1, valueBytes2}
231230
metadata := cspann.PartitionMetadata{
232-
Level: cspann.SecondLevel, Centroid: quantizedSet.GetCentroid()}
231+
Level: cspann.SecondLevel,
232+
Centroid: quantizedSet.GetCentroid(),
233+
StateDetails: cspann.MakeReadyDetails(),
234+
}
233235
partition := cspann.NewPartition(
234236
metadata, suite.quantizer, quantizedSet, childKeys, valueBytes)
235237

@@ -400,18 +402,12 @@ func (suite *StoreTestSuite) TestTryCreateEmptyPartition() {
400402
treeKey := store.MakeTreeKey(suite.T(), treeID)
401403
partitionKey := cspann.PartitionKey(10)
402404
centroid := vector.T{4, 3}
403-
timestamp := timeutil.Now()
404405

405406
// Create empty partition.
406407
metadata := cspann.PartitionMetadata{
407-
Level: cspann.SecondLevel,
408-
Centroid: centroid,
409-
StateDetails: cspann.PartitionStateDetails{
410-
State: cspann.SplittingState,
411-
Target1: 20,
412-
Target2: 30,
413-
Timestamp: timestamp,
414-
},
408+
Level: cspann.SecondLevel,
409+
Centroid: centroid,
410+
StateDetails: cspann.MakeSplittingDetails(20, 30),
415411
}
416412
suite.NoError(store.TryCreateEmptyPartition(suite.ctx, treeKey, partitionKey, metadata))
417413

@@ -500,21 +496,16 @@ func (suite *StoreTestSuite) TestTryGetPartition() {
500496
treeKey := store.MakeTreeKey(suite.T(), treeID)
501497
partitionKey := cspann.PartitionKey(10)
502498
centroid := vector.T{4, 3}
503-
timestamp := timeutil.Now()
504499

505500
// Partition does not yet exist.
506501
_, err := store.TryGetPartition(suite.ctx, treeKey, partitionKey)
507502
suite.ErrorIs(err, cspann.ErrPartitionNotFound)
508503

509504
// Create partition with some vectors in it.
510505
metadata := cspann.PartitionMetadata{
511-
Level: cspann.LeafLevel,
512-
Centroid: centroid,
513-
StateDetails: cspann.PartitionStateDetails{
514-
State: cspann.UpdatingState,
515-
Source: 20,
516-
Timestamp: timestamp,
517-
},
506+
Level: cspann.LeafLevel,
507+
Centroid: centroid,
508+
StateDetails: cspann.MakeUpdatingDetails(20),
518509
}
519510
suite.NoError(store.TryCreateEmptyPartition(suite.ctx, treeKey, partitionKey, metadata))
520511
vectors := vector.MakeSet(2)
@@ -576,11 +567,7 @@ func (suite *StoreTestSuite) TestTryGetPartitionMetadata() {
576567
// Update the metadata and verify we get the updated values.
577568
expected := *partition.Metadata()
578569
metadata := expected
579-
metadata.StateDetails = cspann.PartitionStateDetails{
580-
State: cspann.UpdatingState,
581-
Source: 30,
582-
Timestamp: timeutil.Now(),
583-
}
570+
metadata.StateDetails = cspann.MakeUpdatingDetails(30)
584571
suite.NoError(store.TryUpdatePartitionMetadata(
585572
suite.ctx, treeKey, partitionKey, metadata, expected))
586573

@@ -661,17 +648,12 @@ func (suite *StoreTestSuite) TestTryAddToPartition() {
661648
treeKey := store.MakeTreeKey(suite.T(), treeID)
662649
partitionKey := cspann.PartitionKey(10)
663650
centroid := vector.T{4, 3}
664-
timestamp := timeutil.Now()
665651

666652
// Partition does not yet exist.
667653
metadata := cspann.PartitionMetadata{
668-
Level: cspann.LeafLevel,
669-
Centroid: centroid,
670-
StateDetails: cspann.PartitionStateDetails{
671-
State: cspann.UpdatingState,
672-
Source: 20,
673-
Timestamp: timestamp,
674-
},
654+
Level: cspann.LeafLevel,
655+
Centroid: centroid,
656+
StateDetails: cspann.MakeUpdatingDetails(20),
675657
}
676658
addVectors := vector.MakeSet(2)
677659
addVectors.Add(vec1)
@@ -854,12 +836,9 @@ func (suite *StoreTestSuite) createTestPartition(
854836
) (cspann.PartitionKey, *cspann.Partition) {
855837
partitionKey := cspann.PartitionKey(10)
856838
metadata := cspann.PartitionMetadata{
857-
Level: cspann.SecondLevel,
858-
Centroid: vector.T{4, 3},
859-
StateDetails: cspann.PartitionStateDetails{
860-
State: cspann.ReadyState,
861-
Timestamp: timeutil.Now(),
862-
},
839+
Level: cspann.SecondLevel,
840+
Centroid: vector.T{4, 3},
841+
StateDetails: cspann.MakeReadyDetails(),
863842
}
864843
suite.NoError(store.TryCreateEmptyPartition(suite.ctx, treeKey, partitionKey, metadata))
865844
vectors := vector.MakeSet(2)
@@ -973,7 +952,10 @@ func (suite *StoreTestSuite) insertLeafPartition(store TestStore, treeID int) cs
973952
childKeys := []cspann.ChildKey{primaryKey1, primaryKey2, primaryKey3}
974953
valueBytes := []cspann.ValueBytes{valueBytes1, valueBytes2, valueBytes3}
975954
metadata := cspann.PartitionMetadata{
976-
Level: cspann.LeafLevel, Centroid: quantizedSet.GetCentroid()}
955+
Level: cspann.LeafLevel,
956+
Centroid: quantizedSet.GetCentroid(),
957+
StateDetails: cspann.MakeReadyDetails(),
958+
}
977959
partition := cspann.NewPartition(
978960
metadata, suite.quantizer, quantizedSet, childKeys, valueBytes)
979961

@@ -1117,7 +1099,10 @@ func (suite *StoreTestSuite) setRootPartition(store TestStore, treeID int) {
11171099
childKeys := []cspann.ChildKey{partitionKey1, partitionKey2}
11181100
valueBytes := []cspann.ValueBytes{valueBytes1, valueBytes2}
11191101
metadata := cspann.PartitionMetadata{
1120-
Level: cspann.SecondLevel, Centroid: quantizedSet.GetCentroid()}
1102+
Level: cspann.SecondLevel,
1103+
Centroid: quantizedSet.GetCentroid(),
1104+
StateDetails: cspann.MakeReadyDetails(),
1105+
}
11211106
newRoot := cspann.NewPartition(
11221107
metadata, suite.rootQuantizer, quantizedSet, childKeys, valueBytes)
11231108

pkg/sql/vecindex/cspann/fixup_worker.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,10 @@ func (fw *fixupWorker) splitPartition(
309309
}
310310
valueBytes := make([]ValueBytes, 2)
311311
rootMetadata := PartitionMetadata{
312-
Level: partition.Level() + 1, Centroid: quantizedSet.GetCentroid()}
312+
Level: partition.Level() + 1,
313+
Centroid: quantizedSet.GetCentroid(),
314+
StateDetails: MakeReadyDetails(),
315+
}
313316
rootPartition := NewPartition(
314317
rootMetadata, fw.index.rootQuantizer, quantizedSet, childKeys, valueBytes)
315318
if err = fw.txn.SetRootPartition(ctx, fw.treeKey, rootPartition); err != nil {
@@ -623,7 +626,11 @@ func (fw *fixupWorker) mergePartition(
623626
return errors.AssertionFailedf("only root partition can have zero vectors")
624627
}
625628
quantizedSet := fw.index.rootQuantizer.Quantize(&fw.workspace, vectors)
626-
metadata := PartitionMetadata{Level: partition.Level(), Centroid: quantizedSet.GetCentroid()}
629+
metadata := PartitionMetadata{
630+
Level: partition.Level(),
631+
Centroid: quantizedSet.GetCentroid(),
632+
StateDetails: MakeReadyDetails(),
633+
}
627634
rootPartition := NewPartition(
628635
metadata, fw.index.rootQuantizer, quantizedSet, partition.ChildKeys(), partition.ValueBytes())
629636
if err = fw.txn.SetRootPartition(ctx, fw.treeKey, rootPartition); err != nil {

pkg/sql/vecindex/cspann/index.go

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,10 @@ type FormatOptions struct {
918918
// PrimaryKeyStrings, if true, indicates that primary key bytes should be
919919
// interpreted as strings. This is used for testing scenarios.
920920
PrimaryKeyStrings bool
921+
// RootPartitionKey is the key of the partition that is used as the root of
922+
// the formatted output. If this is InvalidKey, then RootKey is used by
923+
// default.
924+
RootPartitionKey PartitionKey
921925
}
922926

923927
// Format formats the vector index as a tree-formatted string similar to this,
@@ -933,7 +937,7 @@ type FormatOptions struct {
933937
// values are rounded to 4 decimal places. Centroids are printed next to
934938
// partition keys.
935939
func (vi *Index) Format(
936-
ctx context.Context, idxCtx *Context, treeKey TreeKey, options FormatOptions,
940+
ctx context.Context, treeKey TreeKey, options FormatOptions,
937941
) (str string, err error) {
938942
// Write formatted bytes to this buffer.
939943
var buf bytes.Buffer
@@ -953,15 +957,24 @@ func (vi *Index) Format(
953957

954958
var helper func(partitionKey PartitionKey, parentPrefix string, childPrefix string) error
955959
helper = func(partitionKey PartitionKey, parentPrefix string, childPrefix string) error {
956-
partition, err := idxCtx.txn.GetPartition(ctx, treeKey, partitionKey)
960+
partition, err := vi.store.TryGetPartition(ctx, treeKey, partitionKey)
957961
if err != nil {
958962
if errors.Is(err, ErrPartitionNotFound) {
959-
// This should never happen, and indicates a bug in the vector index
960-
// implementation. Fallback to showing MISSING.
963+
// Something else might be modifying the tree as we're trying to
964+
// print it. Fallback to showing MISSING.
961965
buf.WriteString(parentPrefix)
962966
buf.WriteString("• ")
963967
buf.WriteString(strconv.FormatInt(int64(partitionKey), 10))
964-
buf.WriteString(" (MISSING)\n")
968+
969+
// If this is the root partition, then show synthesized empty
970+
// partition.
971+
if partitionKey == RootKey {
972+
centroid := make(vector.T, vi.quantizer.GetDims())
973+
buf.WriteByte(' ')
974+
utils.WriteVector(&buf, centroid, 4)
975+
} else {
976+
buf.WriteString(" (MISSING)\n")
977+
}
965978
return nil
966979
}
967980
return err
@@ -976,6 +989,12 @@ func (vi *Index) Format(
976989
buf.WriteString(strconv.FormatInt(int64(partitionKey), 10))
977990
buf.WriteByte(' ')
978991
utils.WriteVector(&buf, original, 4)
992+
details := partition.Metadata().StateDetails
993+
if details.State != ReadyState {
994+
buf.WriteString(" [")
995+
buf.WriteString(details.String())
996+
buf.WriteByte(']')
997+
}
979998
buf.WriteByte('\n')
980999

9811000
if partition.Count() == 0 {
@@ -995,7 +1014,10 @@ func (vi *Index) Format(
9951014

9961015
if partition.Level() == LeafLevel {
9971016
refs := []VectorWithKey{{Key: childKey}}
998-
if err = idxCtx.txn.GetFullVectors(ctx, treeKey, refs); err != nil {
1017+
err = vi.store.RunTransaction(ctx, func(tx Txn) error {
1018+
return tx.GetFullVectors(ctx, treeKey, refs)
1019+
})
1020+
if err != nil {
9991021
return err
10001022
}
10011023
buf.WriteString(parentPrefix)
@@ -1029,7 +1051,11 @@ func (vi *Index) Format(
10291051
return nil
10301052
}
10311053

1032-
if err = helper(RootKey, "", ""); err != nil {
1054+
rootKey := options.RootPartitionKey
1055+
if rootKey == InvalidKey {
1056+
rootKey = RootKey
1057+
}
1058+
if err = helper(rootKey, "", ""); err != nil {
10331059
return "", err
10341060
}
10351061
return buf.String(), nil

0 commit comments

Comments
 (0)