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 015package 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 */ 024public 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}