Skip to content

Commit

Permalink
make /merge error if any merged body is empty or missing
Browse files Browse the repository at this point in the history
  • Loading branch information
DocSavage committed Oct 3, 2024
1 parent 0292b94 commit b7754a3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 16 deletions.
21 changes: 7 additions & 14 deletions datatype/labelmap/labelidx.go
Original file line number Diff line number Diff line change
Expand Up @@ -717,29 +717,22 @@ func ChangeLabelIndex(d dvid.Data, v dvid.VersionID, label uint64, delta labels.
}

// getMergedIndex gets index data for all labels in a set with possible bounds.
func (d *Data) getMergedIndex(v dvid.VersionID, lbls labels.Set, mutInfo dvid.MutInfo, bounds dvid.Bounds) (*labels.Index, error) {
if len(lbls) == 0 {
return nil, nil
}
idx := new(labels.Index)
for label := range lbls {
idx2, err := GetLabelIndex(d, v, label, false)
if err != nil {
return nil, err
}
if err := d.addMutcache(v, mutInfo.MutID, idx2); err != nil {
func (d *Data) getMergedIndex(v dvid.VersionID, mergedIdxs map[uint64]*labels.Index, mutInfo dvid.MutInfo, bounds dvid.Bounds) (*labels.Index, error) {
combinedIdx := new(labels.Index)
for label, idx := range mergedIdxs {
if err := d.addMutcache(v, mutInfo.MutID, idx); err != nil {
dvid.Criticalf("unable to add merge mutid %d index %d: %v\n", mutInfo.MutID, label, err)
}
if bounds.Block != nil && bounds.Block.IsSet() {
if err := idx2.FitToBounds(bounds.Block); err != nil {
if err := idx.FitToBounds(bounds.Block); err != nil {
return nil, err
}
}
if err := idx.Add(idx2, mutInfo); err != nil {
if err := combinedIdx.Add(idx, mutInfo); err != nil {
return nil, err
}
}
return idx, nil
return combinedIdx, nil
}

// given supervoxels with given mapping and whether they were actually in in-memory SVMap, check
Expand Down
14 changes: 13 additions & 1 deletion datatype/labelmap/mutate.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ func (d *Data) MergeLabels(v dvid.VersionID, op labels.MergeOp, info dvid.ModInf
MergeOp: op,
}

// Return error if any of the merged bodies don't exist or are empty.
mergedIdxs := make(map[uint64]*labels.Index, len(op.Merged))
for label := range op.Merged {
if mergedIdxs[label], err = GetLabelIndex(d, v, label, false); err != nil {
return 0, fmt.Errorf("error getting label index for merge label %d: %v", label, err)
} else if mergedIdxs[label] == nil {
return 0, fmt.Errorf("can't merge non-existent label %d", label)
} else if mergedIdxs[label].NumVoxels() == 0 {
return 0, fmt.Errorf("can't merge label %d with no voxels", label)
}
}

// Get all the affected blocks in the merge.
var targetIdx, mergeIdx *labels.Index
if targetIdx, err = GetLabelIndex(d, v, op.Target, false); err != nil {
Expand All @@ -100,7 +112,7 @@ func (d *Data) MergeLabels(v dvid.VersionID, op labels.MergeOp, info dvid.ModInf
dvid.Criticalf("unable to add merge mutid %d target index %d: %v\n", mutID, op.Target, err)
}
delta.TargetVoxels = targetIdx.NumVoxels()
if mergeIdx, err = d.getMergedIndex(v, op.Merged, mutInfo, dvid.Bounds{}); err != nil {
if mergeIdx, err = d.getMergedIndex(v, mergedIdxs, mutInfo, dvid.Bounds{}); err != nil {
err = fmt.Errorf("can't get block indices of merge labels %s: %v", op.Merged, err)
return
}
Expand Down
18 changes: 17 additions & 1 deletion datatype/labelmap/mutate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -825,8 +825,24 @@ func TestMergeLabels(t *testing.T) {
t.Errorf("Expected label 4, got label %d\n", labels[3])
}

// Make sure merging a bad label will result in a no-op with no change in target.
testMerge := mergeJSON(`[2, 3, 10]`)
if err := testMerge.sendErr(t, uuid, "labels"); err == nil {
t.Fatalf("Expected error from bad merge label, got none\n")
}
reqStr = fmt.Sprintf("%snode/%s/labels/supervoxels/2", server.WebAPIPath, uuid)
r = server.TestHTTP(t, "GET", reqStr, nil)
if err := json.Unmarshal(r, &supervoxels); err != nil {
t.Errorf("Unable to parse supervoxels from server. Got: %v\n", supervoxels)
}
if len(supervoxels) != 1 || supervoxels[0] != 2 {
t.Fatalf("expected body 2 to only have supervoxel 2, got %v\n", supervoxels)
}

// Make sure merging an empty label

// Test merge of 3 into 2
testMerge := mergeJSON(`[2, 3]`)
testMerge = mergeJSON(`[2, 3]`)
testMerge.send(t, uuid, "labels")

// Make sure label 3 sparsevol has been removed.
Expand Down

0 comments on commit b7754a3

Please sign in to comment.