summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/clj/clojure/core.clj51
-rw-r--r--src/jvm/clojure/lang/ArrayChunk.java9
-rw-r--r--src/jvm/clojure/lang/ChunkBuffer.java12
-rw-r--r--src/jvm/clojure/lang/ChunkedCons.java29
-rw-r--r--src/jvm/clojure/lang/IChunk.java19
-rw-r--r--src/jvm/clojure/lang/IChunkedSeq.java2
-rw-r--r--src/jvm/clojure/lang/LazilyPersistentVector.java2
-rw-r--r--src/jvm/clojure/lang/PersistentVector.java2
8 files changed, 90 insertions, 36 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 4c76d9b5..022c43ac 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -1493,6 +1493,38 @@
:arglists '([pred coll])}
not-any? (comp not some))
+(defn chunk-buffer [capacity]
+ (clojure.lang.ChunkBuffer. capacity))
+
+(defn chunk-append [#^clojure.lang.ChunkBuffer b x]
+ (.add b x))
+
+(defn chunk [#^clojure.lang.ChunkBuffer b]
+ (.chunk b))
+
+(defn #^clojure.lang.IChunk chunk-first [#^clojure.lang.IChunkedSeq s]
+ (.chunkedFirst s))
+
+(defn #^clojure.lang.ISeq chunk-rest [#^clojure.lang.IChunkedSeq s]
+ (.chunkedMore s))
+
+(defn #^clojure.lang.ISeq chunk-next [#^clojure.lang.IChunkedSeq s]
+ (.chunkedNext s))
+
+(defn chunk-cons [chunk rest]
+ (if (zero? (count chunk))
+ rest
+ (clojure.lang.ChunkedCons. chunk rest)))
+
+(defn chunked-seq? [s]
+ (instance? clojure.lang.IChunkedSeq s))
+
+(defn int
+ "Coerce to int"
+ {:tag Integer
+ :inline (fn [x] `(. clojure.lang.RT (intCast ~x)))}
+ [x] (. clojure.lang.RT (intCast x)))
+
(defn map
"Returns a lazy sequence consisting of the result of applying f to the
set of first items of each coll, followed by applying f to the set
@@ -1502,7 +1534,16 @@
([f coll]
(lazy-seq
(when-let [s (seq coll)]
- (cons (f (first s)) (map f (rest s))))))
+ (if (chunked-seq? s)
+ (let [c (chunk-first s)
+ size (int (count c))
+ b (chunk-buffer size)]
+ (loop [i (int 0)]
+ (when (< i size)
+ (chunk-append b (f (nth c i)))
+ (recur (inc i))))
+ (chunk-cons (chunk b) (map f (chunk-rest s))))
+ (cons (f (first s)) (map f (rest s)))))))
([f c1 c2]
(lazy-seq
(let [s1 (seq c1) s2 (seq c2)]
@@ -1898,12 +1939,6 @@
:inline (fn [x] `(. clojure.lang.Numbers (num ~x)))}
[x] (. clojure.lang.Numbers (num x)))
-(defn int
- "Coerce to int"
- {:tag Integer
- :inline (fn [x] `(. clojure.lang.RT (intCast ~x)))}
- [x] (. clojure.lang.RT (intCast x)))
-
(defn long
"Coerce to long"
{:tag Long
@@ -4154,7 +4189,7 @@
Returns a promise object that can be read with deref/@, and set,
once only, with deliver. Calls to deref/@ prior to delivery will
block. All subsequent derefs will return the same delivered value
- without blocking."
+ without blocking."
[]
(let [d (java.util.concurrent.CountDownLatch. 1)
v (atom nil)]
diff --git a/src/jvm/clojure/lang/ArrayChunk.java b/src/jvm/clojure/lang/ArrayChunk.java
index 08f863cf..90264c57 100644
--- a/src/jvm/clojure/lang/ArrayChunk.java
+++ b/src/jvm/clojure/lang/ArrayChunk.java
@@ -12,7 +12,7 @@
package clojure.lang;
-public final class ArrayChunk implements Indexed{
+public final class ArrayChunk implements IChunk{
final Object[] array;
final int off;
@@ -39,4 +39,11 @@ public Object nth(int i){
public int count(){
return end - off;
}
+
+public IChunk dropFirst(){
+ if(off==end)
+ throw new IllegalStateException("dropFirst of empty chunk");
+ return new ArrayChunk(array, off + 1, end);
+}
+
}
diff --git a/src/jvm/clojure/lang/ChunkBuffer.java b/src/jvm/clojure/lang/ChunkBuffer.java
index aee01e0e..fd484c90 100644
--- a/src/jvm/clojure/lang/ChunkBuffer.java
+++ b/src/jvm/clojure/lang/ChunkBuffer.java
@@ -14,24 +14,24 @@ package clojure.lang;
final public class ChunkBuffer implements Counted{
Object[] buffer;
- int offset;
+ int end;
public ChunkBuffer(int capacity){
buffer = new Object[capacity];
- offset = 0;
+ end = 0;
}
public void add(Object o){
- buffer[offset++] = o;
+ buffer[end++] = o;
}
-public Indexed chunk(){
- ArrayChunk ret = new ArrayChunk(buffer, 0, offset);
+public IChunk chunk(){
+ ArrayChunk ret = new ArrayChunk(buffer, 0, end);
buffer = null;
return ret;
}
public int count(){
- return offset;
+ return end;
}
}
diff --git a/src/jvm/clojure/lang/ChunkedCons.java b/src/jvm/clojure/lang/ChunkedCons.java
index 37f5f47c..b52bc2b6 100644
--- a/src/jvm/clojure/lang/ChunkedCons.java
+++ b/src/jvm/clojure/lang/ChunkedCons.java
@@ -14,51 +14,44 @@ package clojure.lang;
final public class ChunkedCons extends ASeq implements IChunkedSeq{
-final Indexed chunk;
+final IChunk chunk;
final ISeq _more;
-final int offset;
-ChunkedCons(IPersistentMap meta, Indexed chunk, int offset, ISeq more){
+ChunkedCons(IPersistentMap meta, IChunk chunk, ISeq more){
super(meta);
this.chunk = chunk;
- this.offset = offset;
this._more = more;
}
-public ChunkedCons(Indexed chunk, ISeq more){
- this(chunk, 0, more);
-}
-public ChunkedCons(Indexed chunk, int offset, ISeq more){
- this.chunk = chunk;
- this.offset = offset;
- this._more = more;
+public ChunkedCons(IChunk chunk, ISeq more){
+ this(null,chunk, more);
}
public Obj withMeta(IPersistentMap meta){
if(meta != _meta)
- return new ChunkedCons(meta, chunk, offset, _more);
+ return new ChunkedCons(meta, chunk, _more);
return this;
}
public Object first(){
- return chunk.nth(offset);
+ return chunk.nth(0);
}
public ISeq next(){
- if(offset + 1 < chunk.count())
- return new ChunkedCons(chunk, offset + 1, _more);
+ if(chunk.count() > 1)
+ return new ChunkedCons(chunk.dropFirst(), _more);
return chunkedNext();
}
public ISeq more(){
- if(offset + 1 < chunk.count())
- return new ChunkedCons(chunk, offset + 1, _more);
+ if(chunk.count() > 1)
+ return new ChunkedCons(chunk.dropFirst(), _more);
if(_more == null)
return PersistentList.EMPTY;
return _more;
}
-public Indexed chunkedFirst(){
+public IChunk chunkedFirst(){
return chunk;
}
diff --git a/src/jvm/clojure/lang/IChunk.java b/src/jvm/clojure/lang/IChunk.java
new file mode 100644
index 00000000..53e9bf08
--- /dev/null
+++ b/src/jvm/clojure/lang/IChunk.java
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) Rich Hickey. All rights reserved.
+ * The use and distribution terms for this software are covered by the
+ * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+ * which can be found in the file epl-v10.html 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, 2009 */
+
+package clojure.lang;
+
+public interface IChunk extends Indexed{
+
+IChunk dropFirst();
+
+}
diff --git a/src/jvm/clojure/lang/IChunkedSeq.java b/src/jvm/clojure/lang/IChunkedSeq.java
index f53c3534..1f69dd3f 100644
--- a/src/jvm/clojure/lang/IChunkedSeq.java
+++ b/src/jvm/clojure/lang/IChunkedSeq.java
@@ -14,7 +14,7 @@ package clojure.lang;
public interface IChunkedSeq extends ISeq{
-Indexed chunkedFirst() throws Exception;
+IChunk chunkedFirst() throws Exception;
ISeq chunkedNext() throws Exception;
diff --git a/src/jvm/clojure/lang/LazilyPersistentVector.java b/src/jvm/clojure/lang/LazilyPersistentVector.java
index 9ffd9170..f3562cae 100644
--- a/src/jvm/clojure/lang/LazilyPersistentVector.java
+++ b/src/jvm/clojure/lang/LazilyPersistentVector.java
@@ -83,7 +83,7 @@ static class ChunkedSeq extends ASeq implements IChunkedSeq, IndexedSeq{
return chunkedNext();
}
- public Indexed chunkedFirst(){
+ public IChunk chunkedFirst(){
return new ArrayChunk(array, offset, end);
}
diff --git a/src/jvm/clojure/lang/PersistentVector.java b/src/jvm/clojure/lang/PersistentVector.java
index 87bd11d7..5c662556 100644
--- a/src/jvm/clojure/lang/PersistentVector.java
+++ b/src/jvm/clojure/lang/PersistentVector.java
@@ -207,7 +207,7 @@ static public final class ChunkedSeq extends ASeq implements IChunkedSeq{
this.offset = offset;
}
- public Indexed chunkedFirst() throws Exception{
+ public IChunk chunkedFirst() throws Exception{
return new ArrayChunk(node, offset);
}