diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/clj/clojure/core.clj | 51 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ArrayChunk.java | 9 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ChunkBuffer.java | 12 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ChunkedCons.java | 29 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IChunk.java | 19 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IChunkedSeq.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LazilyPersistentVector.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentVector.java | 2 |
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); } |