(ns narjure.bag (:require [clojure.data.priority-map :refer [priority-map-keyfn-by]])) | |
TODO take/get semantic and names to be decided | (defprotocol Bag (put-el [this item]) (get-el [this] [this k]) (remove-el [this k]) (take-el [this] [this k]) (count-els [this])) |
TODO must be discussed | (defn randomize-priority [priority] (* (rand) priority)) |
Set some random priority for a new item and slice map. | (defn assoc-to-bag
[col {:keys [key priority] :as v} capacity]
(let [ncol (->> (randomize-priority priority)
(assoc v :rand-priority)
(assoc col key))]
(if (> (count ncol) capacity)
(let [[k] (last ncol)]
(dissoc ncol k))
ncol))) |
(defrecord DefaultBag [capacity queue]
Bag
(put-el [_ item]
(DefaultBag. capacity (assoc-to-bag queue item capacity)))
(get-el [_] (second (peek queue)))
(get-el [_ key] (when-let [el (queue key)] el))
(remove-el [_ key] (DefaultBag. capacity (dissoc queue key)))
(take-el [bag]
(when-let [el (get-el bag)]
[el (remove-el bag (:key el))]))
(take-el [bag k]
(when-let [el (get-el bag k)]
[el (remove-el bag k)]))
(count-els [_] (count queue))) | |
(defn default-bag ([] (default-bag 100)) ([capacity] (DefaultBag. capacity (priority-map-keyfn-by :rand-priority >)))) | |
(extend-protocol Bag nil (put-el [_ el] (put-el (default-bag) el)) (get-el ([_]) ([_ _])) (remove-el [_ _] (default-bag)) (take-el ([_]) ([_ _])) (count-els [_] 0)) | |