+++ /dev/null
-package jalview.util;
-
-import jalview.ext.android.SparseIntArray;
-import jalview.ext.android.SparseShortArray;
-
-/**
- * A class to count occurrences of characters with minimal memory footprint.
- * Sparse arrays of short values are used to hold the counts, with automatic
- * promotion to arrays of int if any count exceeds the maximum value for a
- * short.
- *
- * @author gmcarstairs
- *
- */
-public class SparseCount
-{
- private static final int DEFAULT_PROFILE_SIZE = 2;
-
- /*
- * array of keys (chars) and values (counts)
- * held either as shorts or (if shorts overflow) as ints
- */
- private SparseShortArray shortProfile;
-
- private SparseIntArray intProfile;
-
- /*
- * flag is set true after short overflow occurs
- */
- private boolean useInts;
-
- /**
- * Constructor which initially creates a new sparse array of short values to
- * hold counts.
- *
- * @param profileSize
- */
- public SparseCount(int profileSize)
- {
- this.shortProfile = new SparseShortArray(profileSize);
- }
-
- /**
- * Constructor which allocates an initial count array for only two distinct
- * values (the array will grow if needed)
- */
- public SparseCount()
- {
- this(DEFAULT_PROFILE_SIZE);
- }
-
- /**
- * Adds the given value for the given key (or sets the initial value), and
- * returns the new value
- *
- * @param key
- * @param value
- */
- public int add(int key, int value)
- {
- int newValue = 0;
- if (useInts)
- {
- newValue = intProfile.add(key, value);
- }
- else
- {
- try {
- newValue = shortProfile.add(key, value);
- } catch (ArithmeticException e) {
- handleOverflow();
- newValue = intProfile.add(key, value);
- }
- }
- return newValue;
- }
-
- /**
- * Switch from counting shorts to counting ints
- */
- synchronized void handleOverflow()
- {
- int size = shortProfile.size();
- intProfile = new SparseIntArray(size);
- for (int i = 0; i < size; i++)
- {
- short key = shortProfile.keyAt(i);
- short value = shortProfile.valueAt(i);
- intProfile.put(key, value);
- }
- shortProfile = null;
- useInts = true;
- }
-
- /**
- * Returns the size of the profile (number of distinct items counted)
- *
- * @return
- */
- public int size()
- {
- return useInts ? intProfile.size() : shortProfile.size();
- }
-
- /**
- * Returns the value for the key (zero if no such key)
- *
- * @param key
- * @return
- */
- public int get(int key)
- {
- return useInts ? intProfile.get(key) : shortProfile.get(key);
- }
-
- /**
- * Sets the value for the given key
- *
- * @param key
- * @param value
- */
- public void put(int key, int value)
- {
- if (useInts)
- {
- intProfile.put(key, value);
- }
- else
- {
- shortProfile.put(key, value);
- }
- }
-
- public int keyAt(int k)
- {
- return useInts ? intProfile.keyAt(k) : shortProfile.keyAt(k);
- }
-
- public int valueAt(int k)
- {
- return useInts ? intProfile.valueAt(k) : shortProfile.valueAt(k);
- }
-
- /**
- * Answers true if this object wraps arrays of int values, false if using
- * short values
- *
- * @return
- */
- boolean isUsingInt()
- {
- return useInts;
- }
-}