Skip to content

Commit ff27522

Browse files
committed
first cut of chunked seqs
Chunked seqs, initial Java-side support
1 parent b045a37 commit ff27522

9 files changed

+254
-13
lines changed

clojure.iml

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
<setting name="buildJar" value="true" />
1212
<setting name="mainClass" value="clojure.lang.Compiler" />
1313
</component>
14+
<component name="FacetManager">
15+
<facet type="Clojure" name="Clojure">
16+
<configuration />
17+
</facet>
18+
</component>
1419
<component name="NewModuleRootManager" inherit-compiler-output="false">
1520
<output url="file://$MODULE_DIR$/classes" />
1621
<exclude-output />

src/jvm/clojure/lang/ArrayChunk.java

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Copyright (c) Rich Hickey. All rights reserved.
3+
* The use and distribution terms for this software are covered by the
4+
* Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5+
* which can be found in the file epl-v10.html at the root of this distribution.
6+
* By using this software in any fashion, you are agreeing to be bound by
7+
* the terms of this license.
8+
* You must not remove this notice, or any other, from this software.
9+
**/
10+
11+
/* rich May 24, 2009 */
12+
13+
package clojure.lang;
14+
15+
public class ArrayChunk implements Indexed{
16+
17+
final Object[] array;
18+
final int off;
19+
20+
public ArrayChunk(Object[] array, int off){
21+
this.array = array;
22+
this.off = off;
23+
}
24+
25+
public Object nth(int i){
26+
return array[off + i];
27+
}
28+
29+
public int count(){
30+
return array.length - off;
31+
}
32+
}

src/jvm/clojure/lang/ChunkedCons.java

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Copyright (c) Rich Hickey. All rights reserved.
3+
* The use and distribution terms for this software are covered by the
4+
* Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5+
* which can be found in the file epl-v10.html at the root of this distribution.
6+
* By using this software in any fashion, you are agreeing to be bound by
7+
* the terms of this license.
8+
* You must not remove this notice, or any other, from this software.
9+
**/
10+
11+
/* rich May 25, 2009 */
12+
13+
package clojure.lang;
14+
15+
final public class ChunkedCons extends ASeq implements IChunkedSeq{
16+
17+
final Indexed chunk;
18+
final ISeq _more;
19+
final int offset;
20+
21+
ChunkedCons(IPersistentMap meta, Indexed chunk, int offset, ISeq more){
22+
super(meta);
23+
this.chunk = chunk;
24+
this.offset = offset;
25+
this._more = more;
26+
}
27+
public ChunkedCons(Indexed chunk, ISeq more){
28+
this(chunk, 0, more);
29+
}
30+
31+
public ChunkedCons(Indexed chunk, int offset, ISeq more){
32+
this.chunk = chunk;
33+
this.offset = offset;
34+
this._more = more;
35+
}
36+
37+
public Obj withMeta(IPersistentMap meta){
38+
if(meta != _meta)
39+
return new ChunkedCons(meta, chunk, offset, _more);
40+
return this;
41+
}
42+
43+
public Object first(){
44+
return chunk.nth(offset);
45+
}
46+
47+
public ISeq next(){
48+
if(offset + 1 < chunk.count())
49+
return new ChunkedCons(chunk, offset + 1, _more);
50+
return chunkedNext();
51+
}
52+
53+
public ISeq more(){
54+
if(offset + 1 < chunk.count())
55+
return new ChunkedCons(chunk, offset + 1, _more);
56+
if(_more == null)
57+
return PersistentList.EMPTY;
58+
return _more;
59+
}
60+
61+
public Indexed chunkedFirst(){
62+
return chunk;
63+
}
64+
65+
public ISeq chunkedNext(){
66+
return chunkedMore().seq();
67+
}
68+
69+
public ISeq chunkedMore(){
70+
if(_more == null)
71+
return PersistentList.EMPTY;
72+
return _more;
73+
}
74+
}

src/jvm/clojure/lang/IChunkedSeq.java

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Copyright (c) Rich Hickey. All rights reserved.
3+
* The use and distribution terms for this software are covered by the
4+
* Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5+
* which can be found in the file epl-v10.html at the root of this distribution.
6+
* By using this software in any fashion, you are agreeing to be bound by
7+
* the terms of this license.
8+
* You must not remove this notice, or any other, from this software.
9+
**/
10+
11+
/* rich May 24, 2009 */
12+
13+
package clojure.lang;
14+
15+
public interface IChunkedSeq extends ISeq{
16+
17+
Indexed chunkedFirst() throws Exception;
18+
19+
ISeq chunkedNext() throws Exception;
20+
21+
ISeq chunkedMore() throws Exception;
22+
23+
}

src/jvm/clojure/lang/IPersistentVector.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010
* You must not remove this notice, or any other, from this software.
1111
*/
1212

13-
public interface IPersistentVector extends Associative, Sequential, IPersistentStack, Reversible, Counted{
13+
public interface IPersistentVector extends Associative, Sequential, IPersistentStack, Reversible, Indexed{
1414
int length();
1515

16-
Object nth(int i);
17-
1816
IPersistentVector assocN(int i, Object val);
1917

2018
IPersistentVector cons(Object o);

src/jvm/clojure/lang/Indexed.java

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Copyright (c) Rich Hickey. All rights reserved.
3+
* The use and distribution terms for this software are covered by the
4+
* Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5+
* which can be found in the file epl-v10.html at the root of this distribution.
6+
* By using this software in any fashion, you are agreeing to be bound by
7+
* the terms of this license.
8+
* You must not remove this notice, or any other, from this software.
9+
**/
10+
11+
/* rich May 24, 2009 */
12+
13+
package clojure.lang;
14+
15+
public interface Indexed extends Counted{
16+
Object nth(int i);
17+
}

src/jvm/clojure/lang/LazySeq.java

+21-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
public final class LazySeq extends Obj implements ISeq, List{
1818

1919
private IFn fn;
20+
private Object sv;
2021
private ISeq s;
2122

2223
public LazySeq(IFn fn){
@@ -33,26 +34,43 @@ public Obj withMeta(IPersistentMap meta){
3334
return new LazySeq(meta, seq());
3435
}
3536

36-
final synchronized public ISeq seq(){
37+
final synchronized Object sval(){
3738
if(fn != null)
3839
{
3940
try
4041
{
41-
s = RT.seq(fn.invoke());
42+
sv = fn.invoke();
4243
fn = null;
4344
}
4445
catch(Exception e)
4546
{
4647
throw new RuntimeException(e);
4748
}
4849
}
50+
if(sv != null)
51+
return sv;
52+
return s;
53+
}
54+
55+
final synchronized public ISeq seq(){
56+
sval();
57+
if(sv != null)
58+
{
59+
Object ls = sv;
60+
sv = null;
61+
while(ls instanceof LazySeq)
62+
{
63+
ls = ((LazySeq)ls).sval();
64+
}
65+
s = RT.seq(ls);
66+
}
4967
return s;
5068
}
5169

5270
public int count(){
5371
int c = 0;
5472
for(ISeq s = seq(); s != null; s = s.next())
55-
++c;
73+
++c;
5674
return c;
5775
}
5876

src/jvm/clojure/lang/PersistentVector.java

+77-3
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,24 @@ final int tailoff(){
8989
return cnt - tail.length;
9090
}
9191

92-
public Object nth(int i){
92+
public Object[] nodeFor(int i){
9393
if(i >= 0 && i < cnt)
9494
{
9595
if(i >= tailoff())
96-
return tail[i & 0x01f];
96+
return tail;
9797
Object[] arr = root;
9898
for(int level = shift; level > 0; level -= 5)
9999
arr = (Object[]) arr[(i >>> level) & 0x01f];
100-
return arr[i & 0x01f];
100+
return arr;
101101
}
102102
throw new IndexOutOfBoundsException();
103103
}
104104

105+
public Object nth(int i){
106+
Object[] node = nodeFor(i);
107+
return node[i & 0x01f];
108+
}
109+
105110
public PersistentVector assocN(int i, Object val){
106111
if(i >= 0 && i < cnt)
107112
{
@@ -163,6 +168,75 @@ public PersistentVector cons(Object val){
163168
return new PersistentVector(meta(), cnt + 1, newshift, newroot, new Object[]{val});
164169
}
165170

171+
public IChunkedSeq chunkedSeq(){
172+
if(count() == 0)
173+
return null;
174+
return new ChunkedSeq(this,0,0);
175+
}
176+
177+
static public final class ChunkedSeq extends ASeq implements IChunkedSeq{
178+
179+
final PersistentVector vec;
180+
final Object[] node;
181+
final int i;
182+
final int offset;
183+
184+
public ChunkedSeq(PersistentVector vec, int i, int offset){
185+
this.vec = vec;
186+
this.i = i;
187+
this.offset = offset;
188+
this.node = vec.nodeFor(i);
189+
}
190+
191+
ChunkedSeq(IPersistentMap meta, PersistentVector vec, Object[] node, int i, int offset){
192+
super(meta);
193+
this.vec = vec;
194+
this.node = node;
195+
this.i = i;
196+
this.offset = offset;
197+
}
198+
199+
ChunkedSeq(PersistentVector vec, Object[] node, int i, int offset){
200+
this.vec = vec;
201+
this.node = node;
202+
this.i = i;
203+
this.offset = offset;
204+
}
205+
206+
public Indexed chunkedFirst() throws Exception{
207+
return new ArrayChunk(node, offset);
208+
}
209+
210+
public ISeq chunkedNext(){
211+
if(i + node.length < vec.cnt)
212+
return new ChunkedSeq(vec,i+ node.length,0);
213+
return null;
214+
}
215+
216+
public ISeq chunkedMore(){
217+
ISeq s = chunkedNext();
218+
if(s == null)
219+
return PersistentList.EMPTY;
220+
return s;
221+
}
222+
223+
public Obj withMeta(IPersistentMap meta){
224+
if(meta == this._meta)
225+
return this;
226+
return new ChunkedSeq(meta, vec, node, i, offset);
227+
}
228+
229+
public Object first(){
230+
return node[offset];
231+
}
232+
233+
public ISeq next(){
234+
if(offset + 1 < node.length)
235+
return new ChunkedSeq(vec, node, i, offset + 1);
236+
return chunkedNext();
237+
}
238+
}
239+
166240
public IPersistentCollection empty(){
167241
return EMPTY.withMeta(meta());
168242
}

src/jvm/clojure/lang/RT.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -494,10 +494,10 @@ static public IPersistentMap meta(Object x){
494494
}
495495

496496
public static int count(Object o){
497+
if(o instanceof Counted)
498+
return ((Counted) o).count();
497499
if(o == null)
498500
return 0;
499-
else if(o instanceof Counted)
500-
return ((Counted) o).count();
501501
else if(o instanceof IPersistentCollection) {
502502
ISeq s = seq(o);
503503
o = null;
@@ -712,10 +712,10 @@ static public Object dissoc(Object coll, Object key) throws Exception{
712712
}
713713

714714
static public Object nth(Object coll, int n){
715+
if(coll instanceof Indexed)
716+
return ((Indexed) coll).nth(n);
715717
if(coll == null)
716718
return null;
717-
else if(coll instanceof IPersistentVector)
718-
return ((IPersistentVector) coll).nth(n);
719719
else if(coll instanceof String)
720720
return Character.valueOf(((String) coll).charAt(n));
721721
else if(coll.getClass().isArray())

0 commit comments

Comments
 (0)