Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions controller/distance_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ func resolveMaxDistance(repoConfig config.RepositoryConfig, outputConfig *pb.Out

// filterChangedTargetsByDistance returns targets where 0 <= distance <= maxDist.
// Returns the input slice unchanged when maxDist < 0 (filtering disabled).
// Negative-distance targets (e.g. CHANGE_TYPE_NEW or unreachable from a
// DIRECT seed) are always dropped when the filter is active.
// Negative-distance targets (unreachable from a DIRECT/NEW seed) are always
// dropped when the filter is active.
func filterChangedTargetsByDistance(targets []*pb.ChangedTarget, maxDist int32) []*pb.ChangedTarget {
if maxDist < 0 {
return targets
Expand Down
4 changes: 2 additions & 2 deletions controller/getchangedtargets.go
Original file line number Diff line number Diff line change
Expand Up @@ -799,11 +799,11 @@ func computeDistances(logger *zap.Logger, changedByName map[string]*pb.ChangedTa
}
}

// initialize all distances to -1, means not set, DIRECT targets at 0.
// initialize all distances to -1, means not set, DIRECT and NEW targets at 0.
var queue []string
visited := make(map[string]struct{}, len(changedByName))
for name, ct := range changedByName {
if ct.GetChangeType() == pb.CHANGE_TYPE_DIRECT {
if ct.GetChangeType() == pb.CHANGE_TYPE_DIRECT || ct.GetChangeType() == pb.CHANGE_TYPE_NEW {
ct.Distance = 0
queue = append(queue, name)
visited[name] = struct{}{}
Expand Down
53 changes: 53 additions & 0 deletions controller/getchangedtargets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,59 @@ func TestGetChangedTargets_CacheHitWithDistanceFilter(t *testing.T) {
assert.NotNil(t, sent[1].GetMetadata())
}

func TestComputeDistances_NewTargetsGetDistanceZero(t *testing.T) {
// Graph:
// A (DIRECT) <- B (INDIRECT)
// N (NEW, no deps)
//
// NEW targets should be treated like DIRECT: distance 0, and seed BFS.

meta := &pb.Metadata{
TargetIdMapping: map[int32]string{
1: "A", 2: "B", 3: "N",
},
}

targetsByName := map[string]*pb.OptimizedTarget{
"A": {Id: 1},
"B": {Id: 2, DirectDependencies: []int32{1}},
"N": {Id: 3},
}

changedByName := map[string]*pb.ChangedTarget{
"A": {ChangeType: pb.CHANGE_TYPE_DIRECT},
"B": {ChangeType: pb.CHANGE_TYPE_INDIRECT},
"N": {ChangeType: pb.CHANGE_TYPE_NEW},
}

computeDistances(zap.NewNop(), changedByName, targetsByName, meta, -1)

assert.Equal(t, int32(0), changedByName["A"].GetDistance(), "DIRECT target A should have distance 0")
assert.Equal(t, int32(1), changedByName["B"].GetDistance(), "B depends on DIRECT A, distance should be 1")
assert.Equal(t, int32(0), changedByName["N"].GetDistance(), "NEW target N should have distance 0")
}

func TestComputeDistances_NewTargetsWithMaxDistance(t *testing.T) {
// When maxDistance is set, NEW targets should still get distance 0
// and not be filtered out.

meta := &pb.Metadata{
TargetIdMapping: map[int32]string{1: "N"},
}

targetsByName := map[string]*pb.OptimizedTarget{
"N": {Id: 1},
}

changedByName := map[string]*pb.ChangedTarget{
"N": {ChangeType: pb.CHANGE_TYPE_NEW},
}

computeDistances(zap.NewNop(), changedByName, targetsByName, meta, 1)

assert.Equal(t, int32(0), changedByName["N"].GetDistance(), "NEW target should have distance 0 even with maxDistance set")
}

func TestComputeDistances_NilMetadata(t *testing.T) {
changedByName := map[string]*pb.ChangedTarget{
"A": {ChangeType: pb.CHANGE_TYPE_DIRECT},
Expand Down
6 changes: 3 additions & 3 deletions proto/tango.proto
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ message ChangedTarget {
ChangeType change_type = 1; // Type of the change
OptimizedTarget old_target = 2; // The old target before the change (first revision)
OptimizedTarget new_target = 3; // The new target after the change (second revision)
// Distance from the nearest CHANGE_TYPE_DIRECT target in the reverse dependency graph.
// 0 means the target itself is DIRECT, 1 means it directly depends on a DIRECT target, etc.
// -1 means the distance is not set (e.g., for NEW targets or targets unreachable from DIRECT targets).
// Distance from the nearest CHANGE_TYPE_DIRECT or CHANGE_TYPE_NEW target in the reverse dependency graph.
// 0 means the target itself is DIRECT or NEW, 1 means it directly depends on such a target, etc.
// -1 means the distance is not set (e.g., targets unreachable from DIRECT/NEW targets).
int32 distance = 4;
}

Expand Down
Loading