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 1.4's IdentityHashMap.
019 * It is designed for <em>small</em> collections of objects.
020 *
021 * @author Howard Lewis Ship
022 * @since 4.0
023 */
024 public class ObjectIdentityMap
025 {
026 private int _pairCount = 0;
027
028 // Alternates between keys and values
029
030 private Object[] _pairs;
031
032 /**
033 * Adds or updates a key in the bag.
034 *
035 * @param key
036 * the key to store a value under; an existing value with the key is discarded
037 * @param value
038 * the value to store
039 */
040 public void put(Object key, Object value)
041 {
042 for (int i = 0; i < _pairCount; i++)
043 {
044 int index = 2 * i;
045
046 if (_pairs[index] == key)
047 {
048 _pairs[index + 1] = value;
049 return;
050 }
051 }
052
053 expandPairsIfNeeded();
054
055 int index = 2 * _pairCount;
056
057 _pairs[index] = key;
058 _pairs[index + 1] = value;
059
060 _pairCount++;
061 }
062
063 /**
064 * Returns the object stored for the given key.
065 *
066 * @return the value, or null if the key is not found
067 */
068
069 public Object get(Object key)
070 {
071 for (int i = 0; i < _pairCount; i++)
072 {
073 int index = 2 * i;
074
075 if (_pairs[index] == key)
076 {
077 return _pairs[index + 1];
078 }
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 values
093 // initially.
094
095 int newSize = Math.max(10, 2 * currentSize);
096
097 Object[] newPairsArray = new Object[newSize];
098
099 if (currentSize > 0)
100 System.arraycopy(_pairs, 0, newPairsArray, 0, currentSize);
101
102 _pairs = newPairsArray;
103 }
104 }
105 }