Skip to content

Commit

Permalink
Refactor FrequencyData to use array-based implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
julesjacobsen committed Mar 13, 2019
1 parent cdc7493 commit 9184274
Showing 1 changed file with 37 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public class FrequencyData {

private static final FrequencyData EMPTY_DATA = new FrequencyData(RsId.empty(), Collections.emptyList());

private static final int NUM_FREQ_SOURCES = FrequencySource.values().length;

private static final float VERY_RARE_SCORE = 1f;
private static final float NOT_RARE_SCORE = 0f;

Expand All @@ -46,7 +48,7 @@ public class FrequencyData {
private final float[] values;

public static FrequencyData of(RsId rsId, Collection<Frequency> frequencies) {
return validate(rsId, new ArrayList<>(frequencies));
return validate(rsId, frequencies);
}

public static FrequencyData of(RsId rsId, Frequency frequency) {
Expand All @@ -69,10 +71,7 @@ public static FrequencyData empty() {
return EMPTY_DATA;
}

/**
* IMPORTANT ensure that a copy of the input data has been provided to this method as the contents will be sorted
*/
private static FrequencyData validate(RsId rsId, List<Frequency> frequencies) {
private static FrequencyData validate(RsId rsId, Collection<Frequency> frequencies) {
Objects.requireNonNull(rsId, "RsId cannot be null");
Objects.requireNonNull(frequencies, "frequency data cannot be null");

Expand All @@ -86,21 +85,45 @@ private static FrequencyData validate(RsId rsId, List<Frequency> frequencies) {
return new FrequencyData(rsId, frequencies);
}

private FrequencyData(RsId rsId, List<Frequency> knownFrequencies) {
private FrequencyData(RsId rsId, Collection<Frequency> frequencies) {
this.rsId = rsId.getId();

this.size = knownFrequencies.size();
// use natural ordering by FrequencySource - this class is a kind of EnumMap, but we're using primitives to store
// the values. This means that duplicated FrequencySource will be overwritten. In practice this shouldn't happen
// as they are extracted from a map instance.
Frequency[] sorted = orderByFrequencySource(frequencies);

this.size = countNotNullFrequencies(sorted);
this.sources = new FrequencySource[size];
this.values = new float[size];

// use natural ordering by FrequencySource - this class is a kind of EnumMap
knownFrequencies.sort(Comparator.comparing(Frequency::getSource));
for (int i = 0; i < knownFrequencies.size(); i++) {
Frequency entry = knownFrequencies.get(i);
// consider replacing this with FrequencySource.ordinal().
sources[i] = entry.getSource();
values[i] = entry.getFrequency();
int pos = 0;
for (Frequency entry : sorted) {
if (entry != null) {
sources[pos] = entry.getSource();
values[pos] = entry.getFrequency();
pos++;
}
}
}

private Frequency[] orderByFrequencySource(Collection<Frequency> frequencies) {
Frequency[] sorted = new Frequency[NUM_FREQ_SOURCES];
for (Frequency frequency : frequencies) {
FrequencySource frequencySource = frequency.getSource();
sorted[frequencySource.ordinal()] = frequency;
}
return sorted;
}

private int countNotNullFrequencies(Frequency[] sorted) {
int notNull = 0;
for (Frequency frequency : sorted) {
if (frequency != null) {
notNull++;
}
}
return notNull;
}

//RSID ought to belong to the Variant, not the frequencyData, but its here for convenience
Expand Down

0 comments on commit 9184274

Please sign in to comment.