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

org.elasticsearch.xpack.core.common.stats.EnumCounters Maven / Gradle / Ivy

/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

package org.elasticsearch.xpack.core.common.stats;

import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLongArray;

/**
 * Utility class similar to org.elasticsearch.xpack.core.watcher.common.stats.Counters, but it is using Enum instead
 * of string to identify the counter. The serialization happens using enum ordinals similar to
 * {@link StreamOutput#writeEnum(Enum)}, which means that ordinal for existing enums should remain the same for backward
 * and forward compatibility of the serialization protocol.
 */
public class EnumCounters> implements Writeable {
    private final AtomicLongArray counters;
    private final E[] enums;

    public EnumCounters(Class enumClass) {
        counters = new AtomicLongArray(enumClass.getEnumConstants().length);
        enums = enumClass.getEnumConstants();
    }

    public EnumCounters(StreamInput in, Class enumClass) throws IOException {
        int size = in.readVInt();
        enums = enumClass.getEnumConstants();
        long[] vals = new long[enums.length];
        for (int i = 0; i < size; i++) {
            long val = in.readVLong();
            if (i < vals.length) {
                vals[i] = val;
            }
        }
        counters = new AtomicLongArray(vals);
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        out.writeVInt(counters.length());
        for (int i = 0; i < counters.length(); i++) {
            out.writeVLong(counters.get(i));
        }
    }

    public void set(E name) {
        counters.set(name.ordinal(), 0);
    }

    public void inc(E name) {
        counters.incrementAndGet(name.ordinal());
    }

    public void inc(E name, long count) {
        counters.addAndGet(name.ordinal(), count);
    }

    public long get(E name) {
        return counters.get(name.ordinal());
    }

    public long size() {
        return counters.length();
    }

    public boolean hasCounters() {
        return size() > 0;
    }

    public Map toMap() {
        Map map = new HashMap<>();
        for (E e : enums) {
            map.put(e.name().toLowerCase(Locale.ROOT), counters.get(e.ordinal()));
        }
        return map;
    }

    public static > EnumCounters merge(Class enumClass, List> counters) {
        EnumCounters result = new EnumCounters<>(enumClass);
        E[] enums = enumClass.getEnumConstants();
        for (EnumCounters c : counters) {
            for (E e : enums) {
                result.inc(e, c.get(e));
            }
        }
        return result;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        EnumCounters that = (EnumCounters) o;
        return Arrays.equals(toArray(), that.toArray()) &&
            Arrays.equals(enums, that.enums);
    }

    @Override
    public int hashCode() {
        int result = Arrays.hashCode(toArray());
        result = 31 * result + Arrays.hashCode(enums);
        return result;
    }

    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder("[");
        boolean first = true;
        for (E e : enums) {
            buf.append(e.name().toLowerCase(Locale.ROOT)).append(": ").append(get(e));
            if (first) {
                buf.append(", ");
                first = false;
            }
        }
        buf.append("]");
        return buf.toString();
    }

    private long[] toArray() {
        long[] res = new long[enums.length];
        for (int i = 0; i < res.length; i++) {
            res[i] = counters.get(i);
        }
        return res;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy