net.maizegenetics.util.GeneralAnnotationStorage Maven / Gradle / Ivy
/*
* GeneralAnnotationStorage
*
* Created on Feb. 2, 2015
*/
package net.maizegenetics.util;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Ordering;
import com.google.common.collect.SetMultimap;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
* @author Ed Buckler
* @author Terry Casstevens
*/
public class GeneralAnnotationStorage implements GeneralAnnotation {
public static final GeneralAnnotationStorage EMPTY_ANNOTATION_STORAGE = new GeneralAnnotationStorage();
private static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
private static final int MAX_CACHE_SIZE = 1_000_000;
private static final Map, Map.Entry> CACHE = Collections.synchronizedMap(new LinkedHashMap, Map.Entry>((3 * MAX_CACHE_SIZE) / 2) {
@Override
protected boolean removeEldestEntry(Map.Entry, Map.Entry> eldest) {
return size() > MAX_CACHE_SIZE;
}
});
private static Map.Entry getCanonicalAnnotation(String key, String value) {
Map.Entry temp = new AbstractMap.SimpleImmutableEntry<>(key, value);
Map.Entry entry = CACHE.putIfAbsent(temp, temp);
return (entry == null) ? temp : entry;
}
private final Map.Entry[] myAnnotations;
private GeneralAnnotationStorage(Builder builder) {
myAnnotations = (Map.Entry[]) new Map.Entry, ?>[builder.myAnnotations.size()];
for (int i = 0; i < builder.myAnnotations.size(); i++) {
myAnnotations[i] = builder.myAnnotations.get(i);
}
}
private GeneralAnnotationStorage() {
myAnnotations = (Map.Entry[]) new Map.Entry, ?>[0];
}
public static Builder getBuilder() {
return new Builder();
}
@Override
public String[] getTextAnnotation(String annoName) {
List result = new ArrayList<>(1);
for (Map.Entry me : myAnnotations) {
if (me.getKey().equals(annoName)) {
result.add(me.getValue());
}
}
return result.toArray(new String[result.size()]);
}
@Override
public Map getConcatenatedTextAnnotations() {
Map result = new HashMap<>();
for (Map.Entry me : myAnnotations) {
String value = result.get(me.getKey());
if (value == null) {
result.put(me.getKey(), me.getValue());
} else {
result.put(me.getKey(), value + "," + me.getValue());
}
}
return result;
}
@Override
public double[] getQuantAnnotation(String annoName) {
try {
ArrayList result = new ArrayList<>(1);
for (Map.Entry me : myAnnotations) {
if (me.getKey().equals(annoName)) {
result.add(Double.parseDouble(me.getValue()));
}
}
if (result.isEmpty()) {
return EMPTY_DOUBLE_ARRAY;
}
double[] d = new double[result.size()];
for (int i = 0; i < result.size(); i++) {
d[i] = result.get(i);
}
return d;
} catch (Exception e) {
return EMPTY_DOUBLE_ARRAY;
}
}
@Override
public double getAverageAnnotation(String annoName) {
double[] values = getQuantAnnotation(annoName);
if (values.length == 0) {
return Double.NaN;
} else if (values.length == 1) {
return values[0];
} else {
double result = 0.0;
for (double current : values) {
result += current;
}
return result / (double) values.length;
}
}
@Override
public boolean isAnnotatedWithValue(String annoName, String annoValue) {
for (Map.Entry me : myAnnotations) {
if (me.getKey().equals(annoName) && me.getValue().equals(annoValue)) {
return true;
}
}
return false;
}
@Override
public Map.Entry[] getAllAnnotationEntries() {
return Arrays.copyOf(myAnnotations, myAnnotations.length);
}
@Override
public Set getAnnotationKeys() {
Set result = new HashSet<>();
for (Map.Entry me : myAnnotations) {
result.add(me.getKey());
}
return result;
}
@Override
public SetMultimap getAnnotationAsMap() {
ImmutableSetMultimap.Builder result = new ImmutableSetMultimap.Builder()
.orderKeysBy(Ordering.natural()).orderValuesBy(Ordering.natural());
for (Map.Entry en : myAnnotations) {
result.put(en.getKey(), en.getValue());
}
return result.build();
}
@Override
public int numAnnotations() {
return myAnnotations.length;
}
public static class Builder {
private final List> myAnnotations = new ArrayList<>(0);
private Builder() {
}
public Builder addAnnotation(String key, String value) {
myAnnotations.add(getCanonicalAnnotation(key, value));
return this;
}
public Builder addAnnotation(String key, Number value) {
myAnnotations.add(getCanonicalAnnotation(key, value.toString()));
return this;
}
public Builder addAnnotations(GeneralAnnotation existing) {
if (existing == null) {
return this;
}
myAnnotations.addAll(Arrays.asList(existing.getAllAnnotationEntries()));
return this;
}
public GeneralAnnotationStorage build() {
if (myAnnotations.isEmpty()) {
return EMPTY_ANNOTATION_STORAGE;
}
Collections.sort(myAnnotations, (Map.Entry s1, Map.Entry s2) -> {
int keyComp = s1.getKey().compareTo(s2.getKey());
if (keyComp != 0) {
return keyComp;
}
return s1.getValue().compareTo(s2.getValue());
});
return new GeneralAnnotationStorage(this);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy