From d58a485c03e12553a7d25529b47e20b10ab37215 Mon Sep 17 00:00:00 2001 From: mdb Date: Thu, 6 Feb 2003 19:57:29 +0000 Subject: [PATCH] Get yer integer to object mappings, cheap! git-svn-id: https://samskivert.googlecode.com/svn/trunk@1051 6335cc39-0255-0410-8fd6-9bcaacd3b74c --- .../java/com/samskivert/util/CheapIntMap.java | 100 ++++++++++++++++++ .../com/samskivert/util/CheapIntMapTest.java | 64 +++++++++++ 2 files changed, 164 insertions(+) create mode 100644 projects/samskivert/src/java/com/samskivert/util/CheapIntMap.java create mode 100644 projects/samskivert/tests/src/java/com/samskivert/util/CheapIntMapTest.java diff --git a/projects/samskivert/src/java/com/samskivert/util/CheapIntMap.java b/projects/samskivert/src/java/com/samskivert/util/CheapIntMap.java new file mode 100644 index 00000000..92035d17 --- /dev/null +++ b/projects/samskivert/src/java/com/samskivert/util/CheapIntMap.java @@ -0,0 +1,100 @@ +// +// $Id: CheapIntMap.java,v 1.1 2003/02/06 19:57:29 mdb Exp $ + +package com.samskivert.util; + +import java.util.Arrays; + +/** + * A low overhead hash map using positive integers as keys that is useful + * for fast storage and lookup of a small and bounded number of items. + */ +public class CheapIntMap +{ + /** + * Constructs a map that can hold the specified number of items. + */ + public CheapIntMap (int maxSize) + { + _keys = new int[maxSize]; + _values = new Object[maxSize]; + clear(); + } + + /** + * Inserts the specified value into the map. Note: the key + * must be a positive integer. + */ + public void put (int key, Object value) + { + int size = _keys.length, start = key % size, iidx = -1; + for (int ii = 0; ii < size; ii++) { + int idx = (ii + start) % size; + if (_keys[idx] == key) { + _values[idx] = value; + return; + } else if (iidx == -1 && _keys[idx] == -1) { + iidx = idx; + } + } + + if (iidx != -1) { + _keys[iidx] = key; + _values[iidx] = value; + return; + } + + // they booched it! + String errmsg = "You fool! You've filled up your cheap int map! " + + "[keys=" + StringUtil.toString(_keys) + + ", values=" + StringUtil.toString(_values) + "]"; + throw new RuntimeException(errmsg); + } + + /** + * Returns the object with the specified key, null if no object exists + * in the table with that key. + */ + public Object get (int key) + { + int size = _keys.length, start = key % size; + for (int ii = 0; ii < size; ii++) { + int idx = (ii + start) % size; + if (_keys[idx] == key) { + return _values[idx]; + } + } + return null; + } + + /** + * Removes the mapping associated with the specified key. The previous + * value of the mapping will be returned. + */ + public Object remove (int key) + { + int size = _keys.length, start = key % size; + for (int ii = 0; ii < size; ii++) { + int idx = (ii + start) % size; + if (_keys[idx] == key) { + Object value = _values[idx]; + _keys[idx] = -1; + _values[idx] = null; + return value; + } + } + return null; + } + + /** + * Clears out all mappings from the table. + */ + public void clear () + { + Arrays.fill(_keys, -1); + Arrays.fill(_values, null); + } + + protected int[] _keys; + protected Object[] _values; +} diff --git a/projects/samskivert/tests/src/java/com/samskivert/util/CheapIntMapTest.java b/projects/samskivert/tests/src/java/com/samskivert/util/CheapIntMapTest.java new file mode 100644 index 00000000..510a72c7 --- /dev/null +++ b/projects/samskivert/tests/src/java/com/samskivert/util/CheapIntMapTest.java @@ -0,0 +1,64 @@ +// +// $Id: CheapIntMapTest.java,v 1.1 2003/02/06 19:57:29 mdb Exp $ + +package com.samskivert.util; + +import junit.framework.Test; +import junit.framework.TestCase; + +/** + * Tests the {@link CheapIntMap} class. + */ +public class CheapIntMapTest extends TestCase +{ + public CheapIntMapTest () + { + super(CheapIntMapTest.class.getName()); + } + + public void runTest () + { + CheapIntMap map = new CheapIntMap(10); + + for (int ii = 0; ii < 100; ii += 20) { + map.put(ii, new Integer(ii)); + } + + for (int ii = 0; ii < 5; ii++) { + map.put(ii, new Integer(ii)); + } + + for (int ii = 0; ii < 100; ii++) { + Object val = map.get(ii); + if (val != null) { + System.out.println(ii + " => " + val); + } + } + + for (int ii = 0; ii < 100; ii += 20) { + System.out.println("Removing " + map.remove(ii)); + } + + for (int ii = 10; ii > 0; ii--) { + map.put(ii, new Integer(ii)); + } + + for (int ii = 0; ii < 100; ii++) { + Object val = map.get(ii); + if (val != null) { + System.out.println(ii + " => " + val); + } + } + } + + public static Test suite () + { + return new CheapIntMapTest(); + } + + public static void main (String[] args) + { + CheapIntMapTest test = new CheapIntMapTest(); + test.runTest(); + } +}