|
11 | 11 | package clojure.lang;
|
12 | 12 |
|
13 | 13 | import java.io.Serializable;
|
14 |
| -import java.util.Iterator; |
15 |
| -import java.util.List; |
16 |
| -import java.util.Map; |
| 14 | +import java.util.*; |
| 15 | +import java.util.concurrent.Callable; |
17 | 16 | import java.util.concurrent.atomic.AtomicReference;
|
18 | 17 |
|
19 | 18 | /*
|
@@ -188,6 +187,22 @@ public Object kvreduce(IFn f, Object init){
|
188 | 187 | return init;
|
189 | 188 | }
|
190 | 189 |
|
| 190 | +public Object fold(long n, final IFn combinef, final IFn reducef, |
| 191 | + IFn fjinvoke, final IFn fjtask, final IFn fjfork, final IFn fjjoin){ |
| 192 | + //we are ignoring n for now |
| 193 | + Callable top = new Callable(){ |
| 194 | + public Object call() throws Exception{ |
| 195 | + Object ret = combinef.invoke(); |
| 196 | + if(root != null) |
| 197 | + ret = combinef.invoke(ret, root.fold(combinef,reducef,fjtask,fjfork,fjjoin)); |
| 198 | + return hasNull? |
| 199 | + combinef.invoke(ret,reducef.invoke(combinef.invoke(),null,nullValue)) |
| 200 | + :ret; |
| 201 | + } |
| 202 | + }; |
| 203 | + return fjinvoke.invoke(top); |
| 204 | +} |
| 205 | + |
191 | 206 | public int count(){
|
192 | 207 | return count;
|
193 | 208 | }
|
@@ -324,6 +339,7 @@ static interface INode extends Serializable {
|
324 | 339 |
|
325 | 340 | public Object kvreduce(IFn f, Object init);
|
326 | 341 |
|
| 342 | + Object fold(IFn combinef, IFn reducef, IFn fjtask, IFn fjfork, IFn fjjoin); |
327 | 343 | }
|
328 | 344 |
|
329 | 345 | final static class ArrayNode implements INode{
|
@@ -395,6 +411,52 @@ public Object kvreduce(IFn f, Object init){
|
395 | 411 | return init;
|
396 | 412 | }
|
397 | 413 |
|
| 414 | + public Object fold(final IFn combinef, final IFn reducef, |
| 415 | + final IFn fjtask, final IFn fjfork, final IFn fjjoin){ |
| 416 | + List<Callable> tasks = new ArrayList(); |
| 417 | + for(final INode node : array){ |
| 418 | + if(node != null){ |
| 419 | + tasks.add(new Callable(){ |
| 420 | + public Object call() throws Exception{ |
| 421 | + return node.fold(combinef, reducef, fjtask, fjfork, fjjoin); |
| 422 | + } |
| 423 | + }); |
| 424 | + } |
| 425 | + } |
| 426 | + |
| 427 | + return foldTasks(tasks,combinef,fjtask,fjfork,fjjoin); |
| 428 | + } |
| 429 | + |
| 430 | + static public Object foldTasks(List<Callable> tasks, final IFn combinef, |
| 431 | + final IFn fjtask, final IFn fjfork, final IFn fjjoin){ |
| 432 | + |
| 433 | + if(tasks.isEmpty()) |
| 434 | + return combinef.invoke(); |
| 435 | + |
| 436 | + if(tasks.size() == 1){ |
| 437 | + Object ret = null; |
| 438 | + try |
| 439 | + { |
| 440 | + return tasks.get(0).call(); |
| 441 | + } |
| 442 | + catch(Exception e) |
| 443 | + { |
| 444 | + //aargh |
| 445 | + } |
| 446 | + } |
| 447 | + |
| 448 | + List<Callable> t1 = tasks.subList(0,tasks.size()/2); |
| 449 | + final List<Callable> t2 = tasks.subList(tasks.size()/2, tasks.size()); |
| 450 | + |
| 451 | + Object forked = fjfork.invoke(fjtask.invoke(new Callable() { |
| 452 | + public Object call() throws Exception{ |
| 453 | + return foldTasks(t2,combinef,fjtask,fjfork,fjjoin); |
| 454 | + } |
| 455 | + })); |
| 456 | + |
| 457 | + return combinef.invoke(foldTasks(t1,combinef,fjtask,fjfork,fjjoin),fjjoin.invoke(forked)); |
| 458 | + } |
| 459 | + |
398 | 460 |
|
399 | 461 | private ArrayNode ensureEditable(AtomicReference<Thread> edit){
|
400 | 462 | if(this.edit == edit)
|
@@ -629,6 +691,9 @@ public Object kvreduce(IFn f, Object init){
|
629 | 691 | return NodeSeq.kvreduce(array,f,init);
|
630 | 692 | }
|
631 | 693 |
|
| 694 | + public Object fold(IFn combinef, IFn reducef, IFn fjtask, IFn fjfork, IFn fjjoin){ |
| 695 | + return NodeSeq.kvreduce(array, reducef, combinef.invoke()); |
| 696 | + } |
632 | 697 |
|
633 | 698 | private BitmapIndexedNode ensureEditable(AtomicReference<Thread> edit){
|
634 | 699 | if(this.edit == edit)
|
@@ -818,6 +883,10 @@ public Object kvreduce(IFn f, Object init){
|
818 | 883 | return NodeSeq.kvreduce(array,f,init);
|
819 | 884 | }
|
820 | 885 |
|
| 886 | + public Object fold(IFn combinef, IFn reducef, IFn fjtask, IFn fjfork, IFn fjjoin){ |
| 887 | + return NodeSeq.kvreduce(array, reducef, combinef.invoke()); |
| 888 | + } |
| 889 | + |
821 | 890 | public int findIndex(Object key){
|
822 | 891 | for(int i = 0; i < 2*count; i+=2)
|
823 | 892 | {
|
|
0 commit comments