2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.ext.android.SparseIntArray;
24 import jalview.ext.android.SparseShortArray;
27 * A class to count occurrences of characters with minimal memory footprint.
28 * Sparse arrays of short values are used to hold the counts, with automatic
29 * promotion to arrays of int if any count exceeds the maximum value for a
35 public class SparseCount
37 private static final int DEFAULT_PROFILE_SIZE = 2;
40 * array of keys (chars) and values (counts)
41 * held either as shorts or (if shorts overflow) as ints
43 private SparseShortArray shortProfile;
45 private SparseIntArray intProfile;
48 * flag is set true after short overflow occurs
50 private boolean useInts;
53 * Constructor which initially creates a new sparse array of short values to
58 public SparseCount(int profileSize)
60 this.shortProfile = new SparseShortArray(profileSize);
64 * Constructor which allocates an initial count array for only two distinct
65 * values (the array will grow if needed)
69 this(DEFAULT_PROFILE_SIZE);
73 * Adds the given value for the given key (or sets the initial value), and
74 * returns the new value
79 public int add(int key, int value)
84 newValue = intProfile.add(key, value);
90 newValue = shortProfile.add(key, value);
91 } catch (ArithmeticException e)
94 newValue = intProfile.add(key, value);
101 * Switch from counting shorts to counting ints
103 synchronized void handleOverflow()
105 int size = shortProfile.size();
106 intProfile = new SparseIntArray(size);
107 for (int i = 0; i < size; i++)
109 short key = shortProfile.keyAt(i);
110 short value = shortProfile.valueAt(i);
111 intProfile.put(key, value);
118 * Returns the size of the profile (number of distinct items counted)
124 return useInts ? intProfile.size() : shortProfile.size();
128 * Returns the value for the key (zero if no such key)
133 public int get(int key)
135 return useInts ? intProfile.get(key) : shortProfile.get(key);
139 * Sets the value for the given key
144 public void put(int key, int value)
148 intProfile.put(key, value);
152 shortProfile.put(key, value);
156 public int keyAt(int k)
158 return useInts ? intProfile.keyAt(k) : shortProfile.keyAt(k);
161 public int valueAt(int k)
163 return useInts ? intProfile.valueAt(k) : shortProfile.valueAt(k);
167 * Answers true if this object wraps arrays of int values, false if using