(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)) | |