/** * Copyright (c) Rich Hickey. All rights reserved. * The use and distribution terms for this software are covered by the * Common Public License 1.0 (http://opensource.org/licenses/cpl.php) * which can be found in the file CPL.TXT at the root of this distribution. * By using this software in any fashion, you are agreeing to be bound by * the terms of this license. * You must not remove this notice, or any other, from this software. **/ using System; using System.Collections; namespace org.clojure.runtime { /** * Simple implementation of persistent map on an array * Note that instances of this class are constant values * i.e. add/remove etc return new values * * Copies array on every change, so only appropriate for _very_small_ maps * * null keys and values are ok, but you won't be able to distinguish a null value via get - use contains/find */ public class PersistentArrayMap : IPersistentMap { internal readonly Object[] array; public PersistentArrayMap(){ this.array = RT.EMPTY_ARRAY; } /** * This ctor captures/aliases the passed array, so do not modify later * @param init {key1,val1,key2,val2,...} */ public PersistentArrayMap(Object[] init){ this.array = init; } public int count() { return array.Length/2; } public bool contains(Object key){ return indexOf(key) >= 0; } public IMapEntry find(Object key) { int i = indexOf(key); if(i >= 0) return new Iter(array,i); return null; } public IPersistentMap add(Object key) { return put(key,null); } public IPersistentMap put(Object key, Object val) { int i = indexOf(key); Object[] newArray; if(i >= 0) //already have key, same-sized replacement { if(array[i+1] == val) //no change, no op return this; newArray = (Object[])array.Clone(); newArray[i+1] = val; } else //didn't have key, grow { newArray = new Object[array.Length + 2]; if(array.Length > 0) Array.Copy(array,0,newArray,2,array.Length); newArray[0] = key; newArray[1] = val; } return new PersistentArrayMap(newArray); } public IPersistentMap remove(Object key) { int i = indexOf(key); if(i >= 0) //have key, will remove { Object[] newArray = new Object[array.Length - 2]; for(int s=0,d=0;s= 0) return array[i + 1]; return null; } public int capacity() { return count(); } int indexOf(Object key){ for(int i=0;i