blob: 9437fc07804c490ef7c1e8cf8270e12182bb4e4f [file] [log] [blame]
// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.googlesource.gerrit.plugins.findowners;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Keep owned files and count number of files at control level 1, 2, 3, etc.
*
* <p>A source file can be owned by multiple OWNERS file in its directory or parent directories. The
* owners listed in the lowest OWNERS file has level 1 control of that source file. The 2nd lowest
* OWNERS file has level 2 control, etc.
*
* <p>An owner can own multiple source files at different control level.
*
* <p>Each owner has an OwnerWeights object to keep (0) the set of owned files, (1) number of owned
* files with level 1 control, (2) number of owned files with level 2 control, (3) number of owned
* files with level 3 or higher control,
*/
class OwnerWeights {
static class WeightComparator implements Comparator<String> {
private final Map<String, OwnerWeights> map;
WeightComparator(Map<String, OwnerWeights> weights) {
map = weights;
}
@Override
public int compare(String k1, String k2) {
OwnerWeights w1 = map.get(k1);
OwnerWeights w2 = map.get(k2);
int n1 = w2.countL1 - w1.countL1;
int n2 = w2.countL2 - w1.countL2;
int n3 = w2.countL3 - w1.countL3;
return n1 != 0 ? n1 : (n2 != 0 ? n2 : (n3 != 0 ? n3 : k1.compareTo(k2)));
}
}
Set<String> files = new HashSet<>(); // paths of owned files
int countL1; // number of files with control level 1
int countL2; // number of files with control level 2
int countL3; // number of files with control level 3 or more
/** Return file counters as a compact string. */
String encodeLevelCounts() {
return "[" + countL1 + "+" + countL2 + "+" + countL3 + "]";
}
/** Return file counters as a list of integers. */
List<Integer> getLevelCounts() {
return ImmutableList.of(countL1, countL2, countL3);
}
OwnerWeights(String file, int level) {
addFile(file, level);
}
OwnerWeights() {}
void addFile(String path, int level) {
// If a file is added multiple times,
// it should be added with lowest level first.
if (files.add(path)) {
if (level <= 1) {
countL1++;
} else if (level <= 2) {
countL2++;
} else {
countL3++;
}
}
}
/** Sort keys in weights map by control levels, and return keys. */
static List<String> sortKeys(Map<String, OwnerWeights> weights) {
List<String> keys = new ArrayList<>(weights.keySet());
Collections.sort(keys, new WeightComparator(weights));
return keys;
}
}