Skip to content
Browse files

CRRBV-4: switch to a tweaked version of gvec's VecSeq

  • Loading branch information...
1 parent 04bd70d commit d8941e8b064bebe2b0f13535d39faeb3341d6459 @michalmarczyk michalmarczyk committed Mar 29, 2014
Showing with 67 additions and 5 deletions.
  1. +67 −5 src/main/clojure/clojure/core/rrb_vector/rrbt.clj
View
72 src/main/clojure/clojure/core/rrb_vector/rrbt.clj
@@ -1,5 +1,5 @@
(ns clojure.core.rrb-vector.rrbt
- (:refer-clojure :exclude [assert])
+ (:refer-clojure :exclude [assert ->VecSeq])
(:require [clojure.core.rrb-vector.protocols
:refer [PSliceableVector slicev
PSpliceableVector splicev]]
@@ -13,7 +13,7 @@
[clojure.core.rrb-vector.fork-join :as fj]
[clojure.core.protocols :refer [IKVReduce]]
[clojure.core.reducers :as r :refer [CollFold coll-fold]])
- (:import (clojure.core ArrayManager Vec VecSeq)
+ (:import (clojure.core ArrayManager Vec ArrayChunk)
(clojure.lang RT Util Box PersistentVector
APersistentVector$SubVector)
(clojure.core.rrb_vector.nodes NodeManager)
@@ -48,6 +48,71 @@
(newPath [^java.util.concurrent.atomic.AtomicReference edit ^int shift node])
(doAssoc [^int shift node ^int i val]))
+(deftype VecSeq [^ArrayManager am ^IVecImpl vec anode ^int i ^int offset]
+ clojure.core.protocols.InternalReduce
+ (internal-reduce
+ [_ f val]
+ (loop [result val
+ aidx offset]
+ (if (< aidx (count vec))
+ (let [node (.arrayFor vec aidx)
+ alen (.alength am node)
+ result (loop [result result
+ node-idx 0]
+ (if (< node-idx alen)
+ (recur (f result (.aget am node node-idx))
+ (inc node-idx))
+ result))]
+ (recur result (+ aidx alen)))
+ result)))
+
+ clojure.lang.ISeq
+ (first [_] (.aget am anode offset))
+ (next [this]
+ (if (< (inc offset) (.alength am anode))
+ (new VecSeq am vec anode i (inc offset))
+ (.chunkedNext this)))
+ (more [this]
+ (let [s (.next this)]
+ (or s (clojure.lang.PersistentList/EMPTY))))
+ (cons [this o]
+ (clojure.lang.Cons. o this))
+ (count [this]
+ (loop [i 1
+ s (next this)]
+ (if s
+ (if (instance? clojure.lang.Counted s)
+ (+ i (.count s))
+ (recur (inc i) (next s)))
+ i)))
+ (equiv [this o]
+ (cond
+ (identical? this o) true
+ (or (instance? clojure.lang.Sequential o) (instance? java.util.List o))
+ (loop [me this
+ you (seq o)]
+ (if (nil? me)
+ (nil? you)
+ (and (clojure.lang.Util/equiv (first me) (first you))
+ (recur (next me) (next you)))))
+ :else false))
+ (empty [_]
+ clojure.lang.PersistentList/EMPTY)
+
+
+ clojure.lang.Seqable
+ (seq [this] this)
+
+ clojure.lang.IChunkedSeq
+ (chunkedFirst [_] (ArrayChunk. am anode offset (.alength am anode)))
+ (chunkedNext [_]
+ (let [nexti (+ i (.alength am anode))]
+ (when (< nexti (count vec))
+ (VecSeq. am vec (.arrayFor vec nexti) nexti 0))))
+ (chunkedMore [this]
+ (let [s (.chunkedNext this)]
+ (or s (clojure.lang.PersistentList/EMPTY)))))
+
(defprotocol AsRRBT
(as-rrbt [v]))
@@ -513,9 +578,6 @@
2 (throw (clojure.lang.ArityException.
n (.. this (getClass) (getSimpleName)))))))
- ;; hack to reuse gvec's chunked seqs
- clojure.core.IVecImpl
-
clojure.lang.Seqable
(seq [this]
(if (zero? cnt)

0 comments on commit d8941e8

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