/* * Copyright 2005, Sixth and Red River Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sixrr.metrics.utils; public class StringToFractionMap { private int m_count = 0; private String[] m_keys; private double[] m_numerators; private double[] m_denominators; private static final int INITIAL_SIZE = 11; public StringToFractionMap() { super(); m_keys = new String[INITIAL_SIZE]; m_numerators = new double[INITIAL_SIZE]; m_denominators = new double[INITIAL_SIZE]; } public boolean containsKey(String key) { final int hash = key.hashCode() & 0x7fffffff; final String[] keys = m_keys; final int length = keys.length; int index = hash % length; String cur = keys[index]; if (cur != null && !cur.equals(key)) { final int probe = 1 + hash % (length - 2); do { index -= probe; if (index < 0) { index += length; } cur = keys[index]; } while (cur != null && !cur.equals(key)); } if (cur == null) { return false; } else { return cur.equals(key); } } public void put(String key, double numerator, double denominator) { final int hash = key.hashCode() & 0x7fffffff; final String[] keys = m_keys; final int length = keys.length; int index = hash % length; String cur = keys[index]; if (cur != null && !cur.equals(key)) { final int probe = 1 + hash % (length - 2); do { index -= probe; if (index < 0) { index += length; } cur = keys[index]; } while (cur != null && !cur.equals(key)); } if (cur == null) { keys[index] = key; m_numerators[index] = numerator; m_denominators[index] = denominator; m_count++; if (m_count > m_keys.length >> 1) { rehash(); } } else { m_numerators[index] = numerator; m_denominators[index] = denominator; } } public double get(String key) { final int hash = key.hashCode() & 0x7fffffff; final String[] keys = m_keys; final int length = keys.length; int index = hash % length; String cur = keys[index]; if (cur != null && !cur.equals(key)) { final int probe = 1 + hash % (length - 2); do { index -= probe; if (index < 0) { index += length; } cur = keys[index]; } while (cur != null && !cur.equals(key)); } final double denominator = m_denominators[index]; final double numerator = m_numerators[index]; if (denominator == 0.0) { return 1.0; } return numerator / denominator; } private void rehash() { final int length = PrimeFinder.nextPrime(m_keys.length << 1); final String[] oldkeys = m_keys; final double[] oldNumerators = m_numerators; final double[] oldDenominators = m_denominators; m_keys = new String[length]; m_numerators = new double[length]; m_denominators = new double[length]; final String[] keys = m_keys; final double[] numerators = m_numerators; final double[] denominators = m_denominators; final int oldLength = oldkeys.length; for (int i = 0; i < oldLength; i++) { final String key = oldkeys[i]; if (key != null) { final double numerator = oldNumerators[i]; final double denominator = oldDenominators[i]; final int hash = key.hashCode() & 0x7fffffff; int index = hash % length; String cur = keys[index]; if (cur != null) { final int probe = 1 + hash % (length - 2); do { index -= probe; if (index < 0) { index += length; } cur = keys[index]; } while (cur != null); } keys[index] = key; numerators[index] = numerator; denominators[index] = denominator; } } } public double getMinimum() { double minimum = Double.POSITIVE_INFINITY; for (int i = 0; i < m_numerators.length; i++) { final String key = m_keys[i]; if (key != null) { minimum = Math.min(minimum, m_numerators[i] / m_denominators[i]); } } return minimum; } public double getMaximum() { double max = Double.NEGATIVE_INFINITY; for (int i = 0; i < m_numerators.length; i++) { final String key = m_keys[i]; if (key != null) { max = Math.max(max, m_numerators[i] / m_denominators[i]); } } return max; } public double getTotal() { double total = 0.0; for (int i = 0; i < m_numerators.length; i++) { final String key = m_keys[i]; if (key != null) { total += m_numerators[i] / m_denominators[i]; } } return total; } public double getAverage() { double totalNumerator = 0.0; double totalDenominator = 0.0; for (int i = 0; i < m_numerators.length; i++) { final String key = m_keys[i]; if (key != null) { totalNumerator += m_numerators[i]; totalDenominator += m_denominators[i]; } } if (totalDenominator == 0.0) { return 1.0; } else { return totalNumerator / totalDenominator; } } }