Skip to content
Browse files

first cut of chunked seqs

Chunked seqs, initial Java-side support
1 parent b045a37 commit ff27522840fb3c1681c331ad1fb44a313bd44e0a @richhickey committed
View
5 clojure.iml
@@ -11,6 +11,11 @@
<setting name="buildJar" value="true" />
<setting name="mainClass" value="clojure.lang.Compiler" />
</component>
+ <component name="FacetManager">
+ <facet type="Clojure" name="Clojure">
+ <configuration />
+ </facet>
+ </component>
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/classes" />
<exclude-output />
View
32 src/jvm/clojure/lang/ArrayChunk.java
@@ -0,0 +1,32 @@
+/**
+ * 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 May 24, 2009 */
+
+package clojure.lang;
+
+public class ArrayChunk implements Indexed{
+
+final Object[] array;
+final int off;
+
+public ArrayChunk(Object[] array, int off){
+ this.array = array;
+ this.off = off;
+}
+
+public Object nth(int i){
+ return array[off + i];
+}
+
+public int count(){
+ return array.length - off;
+}
+}
View
74 src/jvm/clojure/lang/ChunkedCons.java
@@ -0,0 +1,74 @@
+/**
+ * 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 May 25, 2009 */
+
+package clojure.lang;
+
+final public class ChunkedCons extends ASeq implements IChunkedSeq{
+
+final Indexed chunk;
+final ISeq _more;
+final int offset;
+
+ChunkedCons(IPersistentMap meta, Indexed chunk, int offset, 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 Obj withMeta(IPersistentMap meta){
+ if(meta != _meta)
+ return new ChunkedCons(meta, chunk, offset, _more);
+ return this;
+}
+
+public Object first(){
+ return chunk.nth(offset);
+}
+
+public ISeq next(){
+ if(offset + 1 < chunk.count())
+ return new ChunkedCons(chunk, offset + 1, _more);
+ return chunkedNext();
+}
+
+public ISeq more(){
+ if(offset + 1 < chunk.count())
+ return new ChunkedCons(chunk, offset + 1, _more);
+ if(_more == null)
+ return PersistentList.EMPTY;
+ return _more;
+}
+
+public Indexed chunkedFirst(){
+ return chunk;
+}
+
+public ISeq chunkedNext(){
+ return chunkedMore().seq();
+}
+
+public ISeq chunkedMore(){
+ if(_more == null)
+ return PersistentList.EMPTY;
+ return _more;
+}
+}
View
23 src/jvm/clojure/lang/IChunkedSeq.java
@@ -0,0 +1,23 @@
+/**
+ * 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 May 24, 2009 */
+
+package clojure.lang;
+
+public interface IChunkedSeq extends ISeq{
+
+Indexed chunkedFirst() throws Exception;
+
+ISeq chunkedNext() throws Exception;
+
+ISeq chunkedMore() throws Exception;
+
+}
View
4 src/jvm/clojure/lang/IPersistentVector.java
@@ -10,11 +10,9 @@
* You must not remove this notice, or any other, from this software.
*/
-public interface IPersistentVector extends Associative, Sequential, IPersistentStack, Reversible, Counted{
+public interface IPersistentVector extends Associative, Sequential, IPersistentStack, Reversible, Indexed{
int length();
-Object nth(int i);
-
IPersistentVector assocN(int i, Object val);
IPersistentVector cons(Object o);
View
17 src/jvm/clojure/lang/Indexed.java
@@ -0,0 +1,17 @@
+/**
+ * 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 May 24, 2009 */
+
+package clojure.lang;
+
+public interface Indexed extends Counted{
+Object nth(int i);
+}
View
24 src/jvm/clojure/lang/LazySeq.java
@@ -17,6 +17,7 @@
public final class LazySeq extends Obj implements ISeq, List{
private IFn fn;
+private Object sv;
private ISeq s;
public LazySeq(IFn fn){
@@ -33,12 +34,12 @@ public Obj withMeta(IPersistentMap meta){
return new LazySeq(meta, seq());
}
-final synchronized public ISeq seq(){
+final synchronized Object sval(){
if(fn != null)
{
try
{
- s = RT.seq(fn.invoke());
+ sv = fn.invoke();
fn = null;
}
catch(Exception e)
@@ -46,13 +47,30 @@ final synchronized public ISeq seq(){
throw new RuntimeException(e);
}
}
+ if(sv != null)
+ return sv;
+ return s;
+}
+
+final synchronized public ISeq seq(){
+ sval();
+ if(sv != null)
+ {
+ Object ls = sv;
+ sv = null;
+ while(ls instanceof LazySeq)
+ {
+ ls = ((LazySeq)ls).sval();
+ }
+ s = RT.seq(ls);
+ }
return s;
}
public int count(){
int c = 0;
for(ISeq s = seq(); s != null; s = s.next())
- ++c;
+ ++c;
return c;
}
View
80 src/jvm/clojure/lang/PersistentVector.java
@@ -89,19 +89,24 @@ final int tailoff(){
return cnt - tail.length;
}
-public Object nth(int i){
+public Object[] nodeFor(int i){
if(i >= 0 && i < cnt)
{
if(i >= tailoff())
- return tail[i & 0x01f];
+ return tail;
Object[] arr = root;
for(int level = shift; level > 0; level -= 5)
arr = (Object[]) arr[(i >>> level) & 0x01f];
- return arr[i & 0x01f];
+ return arr;
}
throw new IndexOutOfBoundsException();
}
+public Object nth(int i){
+ Object[] node = nodeFor(i);
+ return node[i & 0x01f];
+}
+
public PersistentVector assocN(int i, Object val){
if(i >= 0 && i < cnt)
{
@@ -163,6 +168,75 @@ public PersistentVector cons(Object val){
return new PersistentVector(meta(), cnt + 1, newshift, newroot, new Object[]{val});
}
+public IChunkedSeq chunkedSeq(){
+ if(count() == 0)
+ return null;
+ return new ChunkedSeq(this,0,0);
+}
+
+static public final class ChunkedSeq extends ASeq implements IChunkedSeq{
+
+ final PersistentVector vec;
+ final Object[] node;
+ final int i;
+ final int offset;
+
+ public ChunkedSeq(PersistentVector vec, int i, int offset){
+ this.vec = vec;
+ this.i = i;
+ this.offset = offset;
+ this.node = vec.nodeFor(i);
+ }
+
+ ChunkedSeq(IPersistentMap meta, PersistentVector vec, Object[] node, int i, int offset){
+ super(meta);
+ this.vec = vec;
+ this.node = node;
+ this.i = i;
+ this.offset = offset;
+ }
+
+ ChunkedSeq(PersistentVector vec, Object[] node, int i, int offset){
+ this.vec = vec;
+ this.node = node;
+ this.i = i;
+ this.offset = offset;
+ }
+
+ public Indexed chunkedFirst() throws Exception{
+ return new ArrayChunk(node, offset);
+ }
+
+ public ISeq chunkedNext(){
+ if(i + node.length < vec.cnt)
+ return new ChunkedSeq(vec,i+ node.length,0);
+ return null;
+ }
+
+ public ISeq chunkedMore(){
+ ISeq s = chunkedNext();
+ if(s == null)
+ return PersistentList.EMPTY;
+ return s;
+ }
+
+ public Obj withMeta(IPersistentMap meta){
+ if(meta == this._meta)
+ return this;
+ return new ChunkedSeq(meta, vec, node, i, offset);
+ }
+
+ public Object first(){
+ return node[offset];
+ }
+
+ public ISeq next(){
+ if(offset + 1 < node.length)
+ return new ChunkedSeq(vec, node, i, offset + 1);
+ return chunkedNext();
+ }
+}
+
public IPersistentCollection empty(){
return EMPTY.withMeta(meta());
}
View
8 src/jvm/clojure/lang/RT.java
@@ -494,10 +494,10 @@ static public IPersistentMap meta(Object x){
}
public static int count(Object o){
+ if(o instanceof Counted)
+ return ((Counted) o).count();
if(o == null)
return 0;
- else if(o instanceof Counted)
- return ((Counted) o).count();
else if(o instanceof IPersistentCollection) {
ISeq s = seq(o);
o = null;
@@ -712,10 +712,10 @@ static public Object dissoc(Object coll, Object key) throws Exception{
}
static public Object nth(Object coll, int n){
+ if(coll instanceof Indexed)
+ return ((Indexed) coll).nth(n);
if(coll == null)
return null;
- else if(coll instanceof IPersistentVector)
- return ((IPersistentVector) coll).nth(n);
else if(coll instanceof String)
return Character.valueOf(((String) coll).charAt(n));
else if(coll.getClass().isArray())

0 comments on commit ff27522

Please sign in to comment.
Something went wrong with that request. Please try again.