vedang / clj_fdb

A thin Clojure wrapper for the Java API for FoundationDB.
https://vedang.github.io/clj_fdb/
Eclipse Public License 1.0
25 stars 9 forks source link

Implement KeyValue selector functions #7

Closed tirkarthi closed 6 years ago

tirkarthi commented 6 years ago

Is your feature request related to a problem? Please describe.

Implement below functions :

Describe the solution you'd like

They are simple enough to implement. Basically you need to construct range objects with different constructors and then do action similar to get-range by making key value pairs. I have the reference implementation at https://github.com/tirkarthi/clj-foundationdb/blob/master/src/clj_foundationdb/core.clj#L211

Additional context

They provide the flexibility to get the keys greater than or less than the given key.

Python API docs : https://apple.github.io/foundationdb/api-python.html#key-selectors

Java docs : https://apple.github.io/foundationdb/javadoc/com/apple/foundationdb/KeySelector.html

tirkarthi commented 6 years ago

Here is a rough implementation as below :

(defn first-greater-or-equal
  "Takes the following:
  - TransactionContext `tc`
  - key to be stored `k`

  Returns key and value pairs with keys greater than or equal to the given key for the given limit

  Optionally, you can pass in `:keyfn`, `:limit` and `:valfn` as follows:
  "
  [^TransactionContext tc key &
   {:keys [keyfn keyconv-fn valfn limit]
    :or {keyfn bs/to-byte-array
         keyconv-fn identity
         valfn identity
         limit 1}
    :as opts}]
  (let [tr-fn (fn [^Transaction tr]
                (let [key         (KeySelector/firstGreaterOrEqual (keyfn key))
                      end         (.add key limit)
                      range-query (.getRange tr key end)]
                  ;; Refactor it out as a separate call for reuse
                  (reduce (fn [acc ^KeyValue kv]
                            (assoc acc (keyconv-fn (.getKey kv)) (valfn (.getValue kv))))
                          {}
                          range-query)))]
    (ftr/run tc tr-fn)))

I will try to make a PR once I get a good grasp of the API.

vedang commented 6 years ago

Hey @tirkarthi : I'll review this over the weekend and get back to you. I'll update this ticket by Monday EOD.

vedang commented 6 years ago

Hey @tirkarthi :

I reviewed the documentation for KeySelector, and here are my initial thoughts:

  1. I'd like a src/clj_fdb/keyselector.clj file which contains simple wrapper functions over com.apple.foundationdb.KeySelector. These should simply take a byte-array key as input and call the underlying Java functions. This is similar to what I've done in src/clj_fdb/transaction.clj
    • first-greater-than
    • first-greater-or-equal
    • last-less-or-equal
    • last-less-than
  2. I'd like equivalents for these same 4 functions in src/clj_fdb/core.clj which accept a k and a keyfn argument and return an instance of KeySelector. The default for keyfn would be bs/to-byte-array.

I don't want to think about providing any functions more generic / helpful than this at the moment, I want to think about whether these fit into the library or not.

Do you think you can create a PR with above requirements? Let me know if you plan to do that, in that case I won't pick this up myself and will wait on your PR.

tirkarthi commented 6 years ago

Thanks @vedang for the review. The approach looks good to me. Unfortunately I won't be able to pick it up due to lack of time but as you mentioned in the linked issue it's small enough to implement once you have the first implementation since the rest will involve swapping the KeySelecor constructor. I will be able to port back my basic test cases if someone takes a stab at it.

Thanks

vedang commented 6 years ago

Okay! Closing this issue at this point in time.