diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-06-18 19:58:31 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-06-18 19:58:31 +0000 |
commit | 06ad059ae746251384cbf973dee6bd1c1804cab8 (patch) | |
tree | dd1e96d8b7f259aef399ae21d46bb3fe8e811cc8 | |
parent | 8cb60ca5a949f8dea94aea80d9c60b1cd336892c (diff) |
interim checkin
-rw-r--r-- | clojure.iml | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentHashMap.java | 131 |
2 files changed, 132 insertions, 1 deletions
diff --git a/clojure.iml b/clojure.iml index edbba3de..5257eb0f 100644 --- a/clojure.iml +++ b/clojure.iml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <module version="4" relativePaths="true" type="JAVA_MODULE"> <component name="ModuleRootManager" /> - <component name="NewModuleRootManager"> + <component name="NewModuleRootManager" inherit-compiler-output="false"> <output url="file://$MODULE_DIR$/classes" /> <exclude-output /> <content url="file://$MODULE_DIR$"> diff --git a/src/jvm/clojure/lang/PersistentHashMap.java b/src/jvm/clojure/lang/PersistentHashMap.java new file mode 100644 index 00000000..8ab03d11 --- /dev/null +++ b/src/jvm/clojure/lang/PersistentHashMap.java @@ -0,0 +1,131 @@ +/** + * 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. + **/ + +/* rich Jun 18, 2007 */ + +package clojure.lang; + +public class PersistentHashMap { + +final int count; +final INode root; + +static interface INode{ + INode assoc(int level, int hash, Object key, Object val); + INode without(int hash, Object key); + Leaf find(int hash, Object key); +} + +final static class Node implements INode{ + final int bitmap; + final INode[] nodes; + final int level; + + final int mask(int hash) + { + return (hash >>> (5 * level))&0x01f; + } + + final int index(int bit) + { + return Integer.bitCount(bitmap & (bit-1)); + } + + + Node(int bitmap, INode[] nodes, int level){ + this.bitmap = bitmap; + this.nodes = nodes; + this.level = level; + } + + public INode assoc(int level, int hash, Object key, Object val){ + int bit = 1 << mask(hash); + int idx = index(bit); + if((bitmap & bit) != 0) + { + INode n = nodes[idx].assoc(level+1, hash, key, val); + if(n == nodes[idx]) + return this; + else + { + INode[] newnodes = nodes.clone(); + newnodes[idx] = n; + return new Node(bitmap, newnodes, level); + } + } + else + { + INode[] newnodes = new INode[nodes.length + 1]; + for(int i=0;i<idx;++i) + newnodes[i] = nodes[i]; + newnodes[idx] = new Leaf(hash, key, val); + for(int i=idx;i<nodes.length;++i) + newnodes[i+1] = nodes[i]; + return new Node(bitmap | bit, newnodes, level); + } + } + + public INode without(int hash, Object key){ + int bit = 1 << mask(hash); + if((bitmap & bit) != 0) + { + int idx = index(bit); + INode n = nodes[idx].without(hash, key); + if(n != nodes[idx]) + { + if(n == null && bitmap == bit) + { + return null; + } + } + } + return this; + } + + public Leaf find(int hash, Object key){ + int bit = 1 << mask(hash); + if((bitmap & bit) != 0) + { + return nodes[index(bit)].find(hash,key); + } + else + return null; + } +} + +final static class Leaf implements INode{ + final int hash; + final Object key; + final Object val; + + public Leaf(int hash, Object key, Object val){ + this.hash = hash; + this.key = key; + this.val = val; + } + + public INode assoc(int level, int hash, Object key, Object val){ + } + + public INode without(int hash, Object key){ + if(hash == this.hash && key.equals(this.key)) + return null; + return this; + } + + public Leaf find(int hash, Object key){ + if(hash == this.hash && key.equals(this.key)) + return this; + return null; + } +} + +} + |