001 // Copyright 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.tapestry.util;
016
017 /**
018 * A simple map-like collection, similar to (but more more limited than) JDK
019 * 1.4's IdentityHashMap. It is designed for <em>small</em> collections of
020 * objects.
021 *
022 * @author Howard Lewis Ship
023 * @since 4.0
024 */
025 public class ObjectIdentityMap
026 {
027
028 private int _pairCount = 0;
029
030 // Alternates between keys and values
031
032 private Object[] _pairs;
033
034 /**
035 * Adds or updates a key in the bag.
036 *
037 * @param key
038 * the key to store a value under; an existing value with the key
039 * is discarded
040 * @param value
041 * the value to store
042 */
043 public void put(Object key, Object value)
044 {
045 for(int i = 0; i < _pairCount; i++)
046 {
047 int index = 2 * i;
048
049 if (_pairs[index] == key)
050 {
051 _pairs[index + 1] = value;
052 return;
053 }
054 }
055
056 expandPairsIfNeeded();
057
058 int index = 2 * _pairCount;
059
060 _pairs[index] = key;
061 _pairs[index + 1] = value;
062
063 _pairCount++;
064 }
065
066 /**
067 * Returns the object stored for the given key.
068 *
069 * @return the value, or null if the key is not found
070 */
071
072 public Object get(Object key)
073 {
074 for(int i = 0; i < _pairCount; i++)
075 {
076 int index = 2 * i;
077
078 if (_pairs[index] == key) { return _pairs[index + 1]; }
079 }
080
081 return null;
082 }
083
084 private void expandPairsIfNeeded()
085 {
086 int currentSize = _pairs == null ? 0 : _pairs.length;
087
088 int newLength = 2 * (_pairCount + 1);
089
090 if (newLength >= currentSize)
091 {
092 // Expand to dobule current size. Allocate room for 5 keys and 5
093 // values
094 // initially.
095
096 int newSize = Math.max(10, 2 * currentSize);
097
098 Object[] newPairsArray = new Object[newSize];
099
100 if (currentSize > 0)
101 System.arraycopy(_pairs, 0, newPairsArray, 0, currentSize);
102
103 _pairs = newPairsArray;
104 }
105 }
106 }