All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.issues.checks.CheckStats Maven / Gradle / Ivy

package cdc.issues.checks;

import java.lang.reflect.Array;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import cdc.issues.rules.Rule;
import cdc.issues.rules.RuleId;
import cdc.util.lang.Checks;

/**
 * Utility designed to accumulate statistics on passed and ignored checks on items.
 *
 * @author Damien Carbonne
 *
 * @param  The item type, onto which rules are passed or skipped.
 */
public class CheckStats {
    private static class Bucket {
        @SuppressWarnings("unchecked")
        final Set[] sets = (Set[]) Array.newInstance(Set.class, CheckResult.values().length);
    }

    private final Map data = new HashMap<>();
    private final Map counts = new HashMap<>();

    public CheckStats() {
        super();
    }

    /**
     * Clears all accumulated data.
     */
    public void clear() {
        data.clear();
        counts.clear();
    }

    /**
     * Accumulate data on an {@code item}.
     *
     * @param item The checked or ignored item.
     * @param ruleId The {@link RuleId} of the passed or ignored {@link Rule}.
     * @param result The obtained {@link CheckResult}.
     */
    public void add(I item,
                    RuleId ruleId,
                    CheckResult result) {
        Checks.isNotNull(item, "item");
        Checks.isNotNull(ruleId, "ruleId");
        Checks.isNotNull(result, "result");

        final int index = result.ordinal();
        final Bucket bucket = data.computeIfAbsent(item, k -> new Bucket());
        if (bucket.sets[index] == null) {
            bucket.sets[index] = new HashSet<>();
        }
        bucket.sets[index].add(ruleId);
        final int[] c = counts.computeIfAbsent(ruleId, k -> new int[CheckResult.values().length]);
        c[result.ordinal()]++;
    }

    /**
     * @return A Set of all items that were accumulated.
     */
    public Set getItems() {
        return data.keySet();
    }

    /**
     * @return A Set of all {@link RuleId RuleIds} that were accumulated.
     */
    public Set getRuleIds() {
        return counts.keySet();
    }

    /**
     * Return a Set of all {@link RuleId RuleIds} that were accumulated for a given {@code item} with a certain {@link CheckResult}.
     *
     * @param item The item.
     * @param result The {@link CheckResult}.
     * @return A Set of all {@link RuleId RuleIds} that were accumulated for {@code item} with a {@code result}.
     */
    public Set getRuleIds(I item,
                                  CheckResult result) {
        final int index = result.ordinal();
        final Bucket bucket = data.get(item);
        if (bucket == null || bucket.sets[index] == null) {
            return Collections.emptySet();
        } else {
            return bucket.sets[index];
        }
    }

    /**
     * Return the number of entries that were accumulated for a given {@link RuleId} with a certain {@link CheckResult}.
     *
     * @param ruleId The {@link RuleId}.
     * @param result The {@link CheckResult}.
     * @return The number of entries that were accumulated for {@code ruleId} with {@code result}.
     */
    public int getCounts(RuleId ruleId,
                         CheckResult result) {
        final int[] c = counts.get(ruleId);
        if (c == null) {
            return 0;
        } else {
            return c[result.ordinal()];
        }
    }

    /**
     * Return the number of entries that were accumulated for a given {@link RuleId}.
     *
     * @param ruleId The {@link RuleId}.
     * @return The number of entries that were accumulated for {@code ruleId}.
     */
    public int getCounts(RuleId ruleId) {
        final int[] c = counts.get(ruleId);
        if (c == null) {
            return 0;
        } else {
            int total = 0;
            for (final int i : c) {
                total += i;
            }
            return total;
        }
    }

    /**
     * Return the number of entries that were accumulated for a given {@link CheckResult}.
     *
     * @param result The {@link CheckResult}.
     * @return The number of entries that were accumulated for a {@code result}.
     */
    public int getCounts(CheckResult result) {
        int total = 0;
        for (final int[] c : counts.values()) {
            total += c[result.ordinal()];
        }
        return total;
    }

    /**
     * @return The number of entries that were accumulated.
     */
    public int getCounts() {
        int total = 0;
        for (final int[] c : counts.values()) {
            for (final int i : c) {
                total += i;
            }
        }
        return total;
    }
}