<commit_before>;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.

(ns containium.utils.session-store
  (:require [ring.middleware.session.store :refer (SessionStore) :as session]
            [taoensso.nippy :as nippy]))


;;; Helper methods.

(defn deep-merge
  "Like merge-with, but merges maps recursively."
  [& maps]
  (apply
   (fn m [& maps]
     (if (every? map? maps)
       (apply merge-with m maps)
       (last maps)))
   maps))


(defn deep-unmerge
  [m kss]
  (reduce (fn [[extracted leftover] ks]
            [(assoc-in extracted ks (get-in m ks))
             (update-in leftover (butlast ks) dissoc (last ks))])
          [{} m]
          kss))


;;; Serializing session store.

(def default-plain
  [[:noir :session/longlived]
   [:containium/last-db-write]])


(defrecord SerializingSessionStore [session-store serialize deserialize options]
  SessionStore
  (read-session [_ key]
    (when-let [data (session/read-session session-store key)]
      (deep-merge data (deserialize (::serialized data)))))
  (write-session [_ key data]
    (let [[plain to-serialize] (deep-unmerge data (:plain options))
          serialized (assoc plain ::serialized (serialize to-serialize))]
      (session/write-session session-store key serialized)))
  (delete-session [this key]
    (session/delete-session session-store key)))


(defn mk-session-store
  ([session-store]
     (mk-session-store session-store nil))
  ([session-store {:keys [serializer deserializer]<commit_msg>Update deep-merge and deep-unmerge for SerializingSessionStore<commit_after>;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.

(ns containium.utils.session-store
  (:require [ring.middleware.session.store :refer (SessionStore) :as session]
            [taoensso.nippy :as nippy]))


;;; Helper methods.

(defn deep-merge
  "Like merge-with, but merges maps recursively."
  [& maps]
  (apply merge-with
         (fn m [& maps]
           (if (every? map? maps)
             (apply merge-with m maps)
             (last maps)))
         maps))


(defn deep-unmerge
  [m kss]
  (reduce (fn [[extracted leftover] ks]
            [(if-let [v (get-in m ks)] (assoc-in extracted ks v) extracted)
             (update-in leftover (butlast ks) dissoc (last ks))])
          [{} m]
          kss))


;;; Serializing session store.

(def default-plain
  [[:noir :session/longlived]
   [:containium/last-db-write]])


(defrecord SerializingSessionStore [session-store serialize deserialize options]
  SessionStore
  (read-session [_ key]
    (when-let [data (session/read-session session-store key)]
      (deep-merge data (when-let [to-deserialize (::serialized data)]
                         (deserialize to-deserialize)))))
  (write-session [_ key data]
    (let [[plain to-serialize] (deep-unmerge data (:plain options))
          serialized (assoc plain ::serialized (serialize to-serialize))]
      (session/write-session session-store key serialized)))
  (delete-session [this key]
    (session/delete-session session-store key)))


(defn mk-session-store
  ([session-store]
     (mk-session-store session-store nil))
  ([session-store {:keys [serializer deserializer]
{'fraction_non_alphanumeric': 0.130762539866628, 'fraction_numerical': 0.002319512902290519, 'mean_word_length': 3.0492957746478875, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3229169', 'n_tokens_mistral': 1121, 'n_tokens_neox': 1079, 'n_words': 330}