@@ -9547,6 +9547,27 @@ reduces them without incurring seq initialization"
9547
9547
(take-while (mk-bound-fn sc start-test start-key)
9548
9548
(if ((mk-bound-fn sc end-test end-key) e) s (next s))))))
9549
9549
9550
+ (deftype RangeChunk [start step count]
9551
+ ICounted
9552
+ (-count [coll] count)
9553
+
9554
+ ISeq
9555
+ (-first [coll] start)
9556
+
9557
+ IIndexed
9558
+ (-nth [coll i]
9559
+ (+ start (* i step)))
9560
+ (-nth [coll i not-found]
9561
+ (if (and (>= i 0 ) (< i count))
9562
+ (+ start (* i step))
9563
+ not-found))
9564
+
9565
+ IChunk
9566
+ (-drop-first [coll]
9567
+ (if (<= count 1 )
9568
+ (throw (js/Error. " -drop-first of empty chunk" ))
9569
+ (RangeChunk. (+ start step) step (dec count)))))
9570
+
9550
9571
(deftype RangeIterator [^:mutable i end step]
9551
9572
Object
9552
9573
(hasNext [_]
@@ -9558,7 +9579,7 @@ reduces them without incurring seq initialization"
9558
9579
(set! i (+ i step))
9559
9580
ret)))
9560
9581
9561
- (deftype Range [meta start end step ^:mutable __hash]
9582
+ (deftype Range [meta start end step ^:mutable chunk ^:mutable chunk-next ^:mutable __hash]
9562
9583
Object
9563
9584
(toString [coll]
9564
9585
(pr-str* coll))
@@ -9572,30 +9593,34 @@ reduces them without incurring seq initialization"
9572
9593
(-lastIndexOf coll x (count coll)))
9573
9594
(lastIndexOf [coll x start]
9574
9595
(-lastIndexOf coll x start))
9596
+ (forceChunk [coll]
9597
+ (when (nil? chunk)
9598
+ (let [count (-count coll)]
9599
+ (if (> count 32 )
9600
+ (do
9601
+ (set! chunk-next (Range. nil (+ start (* step 32 )) end step nil nil nil ))
9602
+ (set! chunk (RangeChunk. start step 32 )))
9603
+ (set! chunk (RangeChunk. start step count))))))
9575
9604
9576
9605
ICloneable
9577
- (-clone [_] (Range. meta start end step __hash))
9606
+ (-clone [_] (Range. meta start end step chunk chunk-next __hash))
9578
9607
9579
9608
IWithMeta
9580
- (-with-meta [rng meta] (Range. meta start end step __hash))
9609
+ (-with-meta [rng meta] (Range. meta start end step chunk chunk-next __hash))
9581
9610
9582
9611
IMeta
9583
9612
(-meta [rng] meta)
9584
9613
9585
9614
ISeqable
9586
- (-seq [rng]
9587
- (cond
9588
- (pos? step) (when (< start end) rng)
9589
- (neg? step) (when (> start end) rng)
9590
- :else (when-not (== start end) rng)))
9615
+ (-seq [rng] rng)
9591
9616
9592
9617
ISeq
9593
- (-first [rng]
9594
- (when-not (nil? (-seq rng)) start))
9618
+ (-first [rng] start)
9595
9619
(-rest [rng]
9596
- (if-not (nil? (-seq rng))
9597
- (Range. meta (+ start step) end step nil )
9598
- ()))
9620
+ (let [s (-next rng)]
9621
+ (if (nil? s)
9622
+ ()
9623
+ s)))
9599
9624
9600
9625
IIterable
9601
9626
(-iterator [_]
@@ -9605,9 +9630,23 @@ reduces them without incurring seq initialization"
9605
9630
(-next [rng]
9606
9631
(if (pos? step)
9607
9632
(when (< (+ start step) end)
9608
- (Range. meta (+ start step) end step nil ))
9633
+ (Range. meta (+ start step) end step nil nil nil ))
9609
9634
(when (> (+ start step) end)
9610
- (Range. meta (+ start step) end step nil ))))
9635
+ (Range. meta (+ start step) end step nil nil nil ))))
9636
+
9637
+ IChunkedSeq
9638
+ (-chunked-first [rng]
9639
+ (.forceChunk rng)
9640
+ chunk)
9641
+ (-chunked-rest [rng]
9642
+ (.forceChunk rng)
9643
+ (if (nil? chunk-next)
9644
+ ()
9645
+ chunk-next))
9646
+
9647
+ IChunkedNext
9648
+ (-chunked-next [rng]
9649
+ (seq (-chunked-rest rng)))
9611
9650
9612
9651
ICollection
9613
9652
(-conj [rng o] (cons o rng))
@@ -9624,9 +9663,7 @@ reduces them without incurring seq initialization"
9624
9663
9625
9664
ICounted
9626
9665
(-count [rng]
9627
- (if-not (-seq rng)
9628
- 0
9629
- (Math/ceil (/ (- end start) step))))
9666
+ (Math/ceil (/ (- end start) step)))
9630
9667
9631
9668
IIndexed
9632
9669
(-nth [rng n]
@@ -9662,7 +9699,22 @@ reduces them without incurring seq initialization"
9662
9699
([] (range 0 (.-MAX_VALUE js/Number) 1 ))
9663
9700
([end] (range 0 end 1 ))
9664
9701
([start end] (range start end 1 ))
9665
- ([start end step] (Range. nil start end step nil )))
9702
+ ([start end step]
9703
+ (cond
9704
+ (pos? step)
9705
+ (if (<= end start)
9706
+ ()
9707
+ (Range. nil start end step nil nil nil ))
9708
+
9709
+ (neg? step)
9710
+ (if (>= end start)
9711
+ ()
9712
+ (Range. nil start end step nil nil nil ))
9713
+
9714
+ :else
9715
+ (if (== end start)
9716
+ ()
9717
+ (repeat start)))))
9666
9718
9667
9719
(defn take-nth
9668
9720
" Returns a lazy seq of every nth item in coll. Returns a stateful
0 commit comments