summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2009-07-17 17:34:34 -0400
committerRich Hickey <richhickey@gmail.com>2009-07-17 17:34:34 -0400
commitecff9342b455dda737cd585863a695a27a94c19e (patch)
tree5ce84463b3aa7f0d1063cdaa7e6b0882bcc5f1bb
parent53cc7a6c2ed1d3d0bfc4447ecb27d05c4ebd537e (diff)
Clojure interface to editable vectors - mutable,immutable,conj!,pop!,assoc!,get!,nth!
-rw-r--r--src/clj/clojure/core.clj45
-rw-r--r--src/jvm/clojure/lang/PersistentVector.java20
2 files changed, 55 insertions, 10 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 8ed4aaf1..9e742659 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -4315,3 +4315,48 @@
Delivers the supplied value to the promise, releasing any pending
derefs. A subsequent call to deliver on a promise will throw an exception."
[promise val] (promise val))
+
+;;;;;;;;;;;;;;;;;;;;; editable collections ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defn mutable
+ "Returns a new, mutable version of the collection, in constant time."
+ [#^clojure.lang.IEditableCollection coll]
+ (.mutable coll))
+
+(defn immutable
+ "Returns a new, immutable version of the mutable collection, in constant time."
+ [#^clojure.lang.IMutableCollection coll]
+ (.immutable coll))
+
+(defn conj!
+ "Adds x to the mutable collection, and return coll. The 'addition'
+ may happen at different 'places' depending on the concrete type."
+ [#^clojure.lang.IMutableCollection coll x]
+ (.conj coll x))
+
+(defn assoc!
+ "When applied to a mutable map, adds mapping of key(s) to
+ val(s). When applied to a mutable vector, sets the val at index.
+ Note - index must be <= (count vector). Returns coll."
+ ([#^clojure.lang.IMutableAssociative coll key val] (.assoc coll key val))
+ ([#^clojure.lang.IMutableAssociative coll key val & kvs]
+ (let [ret (.assoc coll key val)]
+ (if kvs
+ (recur ret (first kvs) (second kvs) (nnext kvs))
+ ret))))
+
+(defn pop!
+ "Removes the last item from a mutable vector. If
+ the collection is empty, throws an exception. Returns coll"
+ [#^clojure.lang.IMutableVector coll]
+ (.pop coll))
+
+(defn nth!
+ "Returns the value at the index. get! returns nil if index out of
+ bounds, nth! throws an exception"
+ [#^clojure.lang.IMutableVector coll index]
+ (.nth coll index))
+
+(defn get!
+ "Returns the value mapped to key, nil if key not present."
+ [#^clojure.lang.IMutableAssociative coll key]
+ (.valAt coll key))
diff --git a/src/jvm/clojure/lang/PersistentVector.java b/src/jvm/clojure/lang/PersistentVector.java
index 1af75428..c64ad6e6 100644
--- a/src/jvm/clojure/lang/PersistentVector.java
+++ b/src/jvm/clojure/lang/PersistentVector.java
@@ -82,8 +82,8 @@ PersistentVector(IPersistentMap meta, int cnt, int shift, Node root, Object[] ta
this.tail = tail;
}
-public Mutable mutable(){
- return new Mutable(this);
+public MutableVector mutable(){
+ return new MutableVector(this);
}
final int tailoff(){
@@ -371,20 +371,20 @@ private Node popTail(int level, Node node){
}
}
-static class Mutable implements IMutableVector, Counted{
+static class MutableVector implements IMutableVector, Counted{
int cnt;
int shift;
Node root;
Object[] tail;
- Mutable(int cnt, int shift, Node root, Object[] tail){
+ MutableVector(int cnt, int shift, Node root, Object[] tail){
this.cnt = cnt;
this.shift = shift;
this.root = root;
this.tail = tail;
}
- Mutable(PersistentVector v){
+ MutableVector(PersistentVector v){
this(v.cnt, v.shift, editable(v.root), editableTail(v.tail));
}
@@ -420,7 +420,7 @@ static class Mutable implements IMutableVector, Counted{
return ret;
}
- public Mutable conj(Object val){
+ public MutableVector conj(Object val){
ensureEditable();
int i = cnt;
//room in tail?
@@ -510,7 +510,7 @@ static class Mutable implements IMutableVector, Counted{
return node[i & 0x01f];
}
- public Mutable assocN(int i, Object val){
+ public MutableVector assocN(int i, Object val){
ensureEditable();
if(i >= 0 && i < cnt)
{
@@ -528,7 +528,7 @@ static class Mutable implements IMutableVector, Counted{
throw new IndexOutOfBoundsException();
}
- public Mutable assoc(Object key, Object val){
+ public MutableVector assoc(Object key, Object val){
if(Util.isInteger(key))
{
int i = ((Number) key).intValue();
@@ -552,7 +552,7 @@ static class Mutable implements IMutableVector, Counted{
return ret;
}
- public Mutable pop(){
+ public MutableVector pop(){
ensureEditable();
if(cnt == 0)
throw new IllegalStateException("Can't pop empty vector");
@@ -629,7 +629,7 @@ static public void main(String[] args){
//v.setSize(size);
//PersistentArray p = new PersistentArray(size);
PersistentVector p = PersistentVector.EMPTY;
- Mutable mp = p.mutable();
+ MutableVector mp = p.mutable();
for(int i = 0; i < size; i++)
{