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);
89 newValue = shortProfile.add(key, value);
90 } catch (ArithmeticException e) {
92 newValue = intProfile.add(key, value);
99 * Switch from counting shorts to counting ints
101 synchronized void handleOverflow()
103 int size = shortProfile.size();
104 intProfile = new SparseIntArray(size);
105 for (int i = 0; i < size; i++)
107 short key = shortProfile.keyAt(i);
108 short value = shortProfile.valueAt(i);
109 intProfile.put(key, value);
116 * Returns the size of the profile (number of distinct items counted)
122 return useInts ? intProfile.size() : shortProfile.size();
126 * Returns the value for the key (zero if no such key)
131 public int get(int key)
133 return useInts ? intProfile.get(key) : shortProfile.get(key);
137 * Sets the value for the given key
142 public void put(int key, int value)
146 intProfile.put(key, value);
150 shortProfile.put(key, value);
154 public int keyAt(int k)
156 return useInts ? intProfile.keyAt(k) : shortProfile.keyAt(k);
159 public int valueAt(int k)
161 return useInts ? intProfile.valueAt(k) : shortProfile.valueAt(k);
165 * Answers true if this object wraps arrays of int values, false if using