gpt4 book ai didi

java - Clojure 和 HBase : Iterate Lazily over a Scan

转载 作者:太空宇宙 更新时间:2023-11-04 07:39:08 26 4
gpt4 key购买 nike

假设我想在 clojure 中打印 hbase 表扫描的输出。

(defmulti scan (fn [table & args] (map class args)))

(defmethod scan [java.lang.String java.lang.String] [table start-key end-key]
(let [scan (Scan. (Bytes/toBytes start-key) (Bytes/toBytes end-key))]
(let [scanner (.getScanner table scan)]
(doseq [result scanner]
(prn
(Bytes/toString (.getRow result))
(get-to-map result))))))

其中 get-to-map 将结果转换为 map 。它可以像这样运行:

(hbase.table/scan table "key000001" "key999999")

但是如果我想让用户对扫描结果执行某些操作该怎么办?我可以允许他们传递一个函数作为回调来应用于每个结果。但我的问题是:如果我希望用户能够惰性地迭代每个结果,我应该返回什么

(Bytes/toString (.getRow result))
(get-to-map result)

不保留以前的结果,就像在使用惰性序列的简单实现中可能发生的情况一样。

最佳答案

如果您接受回调参数,则可以在 doseq 内调用它:

(defmulti scan [f table & args] (mapv class args)) ; mapv returns vector

(defmethod scan [String String] [f table start-key end-key]
; ^- java.lang classes are imported implicitly
(let [scan ...
scanner ...] ; no need for two separate lets
(doseq [result scanner]
; call f here, e.g.
(f result))))

这里 f 每个结果都会被调用一次。它的返回值以及结果本身将立即被丢弃。您当然可以使用 result 的某些预处理版本来调用 f,例如(f (foo 结果) (bar 结果)).

您还可以将结果序列/vector 返回给客户端,并让它进行自己的处理。如果序列是惰性的,您需要确保支持它的任何资源在处理期间保持打开状态(并且可能稍后将它们关闭 - 请参阅 with-open;处理代码需要在 with-open 内部执行,并在返回时完成处理)。

例如,要将预处理结果的 vector 返回给客户端,您可以这样做

(defmethod scan ...
(let [...]
(mapv (fn preprocess-result [result]
(result->map result))
scanner)))

然后客户端就可以对它们做任何想做的事情。使用 map 返回惰性序列。如果客户端需要打开/关闭资源,您可以接受它作为扫描参数,以便客户端可以说

(with-open [r (some-resource)]
; or mapv, dorun+map, doall+for, ...
(doseq [result (scan r ...)]
(do-stuff-with result)))

关于java - Clojure 和 HBase : Iterate Lazily over a Scan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16328566/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com