diff options
author | David Barksdale <amatus.amongus@gmail.com> | 2012-05-24 23:04:51 -0500 |
---|---|---|
committer | David Barksdale <amatus.amongus@gmail.com> | 2012-05-24 23:04:51 -0500 |
commit | dde3e1addf7ce9773923bb9c9da372668f09baf7 (patch) | |
tree | 10571a877b73a4947904e0756895e866b21649b6 /src | |
parent | 37a9054b5bd833f0d44708c56da798e29063e988 (diff) |
assoc-in achievement unlocked. Cleaned up a bit.
Diffstat (limited to 'src')
-rw-r--r-- | src/clojure/foofs/filesystem.clj | 2 | ||||
-rw-r--r-- | src/clojure/foofs/memorybackend.clj | 194 | ||||
-rw-r--r-- | src/clojure/foofs/util.clj | 8 |
3 files changed, 93 insertions, 111 deletions
diff --git a/src/clojure/foofs/filesystem.clj b/src/clojure/foofs/filesystem.clj index 4171b3a..b11dbc4 100644 --- a/src/clojure/foofs/filesystem.clj +++ b/src/clojure/foofs/filesystem.clj @@ -232,7 +232,7 @@ (fn [state] (agent-do readdir-agent (continuation! (take size encoded-dirents))) - (assoc-deep state encoded-dirents :opendirs handle)))))) + (assoc-in state [:opendirs handle] encoded-dirents)))))) (let [dirents ((:opendirs (deref readdir-agent)) handle)] (continuation! (take size (drop offset dirents))))))) (releasedir [_ {:keys [nodeid arg]} continuation!] diff --git a/src/clojure/foofs/memorybackend.clj b/src/clojure/foofs/memorybackend.clj index efaf97e..24e6f13 100644 --- a/src/clojure/foofs/memorybackend.clj +++ b/src/clojure/foofs/memorybackend.clj @@ -44,7 +44,7 @@ (do (continuation! errno-noent) state) (let [new-inode (f inode)] (agent-do state-agent (continuation! new-inode)) - (assoc-deep state new-inode :inode-table nodeid))))))) + (assoc-in state [:inode-table nodeid] new-inode))))))) (defn attribute-modifier! [state-agent nodeid f attribute continuation!] @@ -103,43 +103,36 @@ (buffer-seq! data) (take tail-size (drop tail-offset file-extended))) - new-size (count file-written)] + new-size (count file-written) + state (assoc-in state [:inode-table nodeid :size] new-size) + state (assoc-in state [:file-table nodeid] file-written)] (agent-do state-agent (continuation! {:size (.limit data)})) - (assoc state - :inode-table (assoc-deep inode-table new-size nodeid :size) - :file-table (assoc file-table nodeid file-written)))))))) + state)))))) (mknod [_ nodeid filename mode continuation!] (send state-agent (fn [state] - (let [lookup-table (:lookup-table state) - children (get lookup-table nodeid) - inode-table (:inode-table state)] - (if (contains? children filename) - (do (continuation! errno-exist) state) - (let [child-nodeid (next-key inode-table (:next-nodeid state) - Long/MIN_VALUE Long/MAX_VALUE) - inode (conj empty-inode - {:mode mode - :nlink 1})] - (agent-do state-agent - (continuation! (assoc inode :nodeid child-nodeid))) - (assoc state - :inode-table (assoc inode-table child-nodeid inode) - :lookup-table (assoc lookup-table nodeid - (assoc children filename - child-nodeid)) - :next-nodeid (inc child-nodeid)))))))) + (if (contains? (get-in state [:lookup-table nodeid]) filename) + (do (continuation! errno-exist) state) + (let [child-nodeid (next-key (:inode-table state) + (:next-nodeid state) + Long/MIN_VALUE Long/MAX_VALUE) + inode (assoc empty-inode :mode mode :nlink 1) + state (assoc-in state [:inode-table child-nodeid] inode) + state (assoc-in state [:lookup-table nodeid filename] + child-nodeid) + state (assoc state :next-nodeid (inc child-nodeid))] + (agent-do state-agent + (continuation! (assoc inode :nodeid child-nodeid))) + state))))) (link [_ nodeid filename target-nodeid continuation!] (send state-agent (fn [state] - (let [lookup-table (:lookup-table state) - inode-table (:inode-table state) - children (get lookup-table nodeid) - inode (get inode-table nodeid) - target-inode (get inode-table target-nodeid)] + (let [children (get-in state [:lookup-table nodeid]) + inode (get-in state [:inode-table nodeid]) + target-inode (get-in state [:inode-table target-nodeid])] (if (contains? children filename) (do (continuation! errno-exist) state) (if (not (= stat-type-directory @@ -147,82 +140,85 @@ (do (continuation! errno-notdir) state) (if (nil? target-inode) (do (continuation! errno-noent) state) - (do + (let [state (assoc-in state [:inode-table target-nodeid :nlink] + (inc (:nlink target-inode))) + state (assoc-in state [:lookup-table nodeid filename] + target-nodeid)] (agent-do state-agent (continuation! (assoc target-inode :nodeid target-nodeid))) - (assoc state - :inode-table (assoc inode-table target-nodeid - (assoc target-inode :nlink - (inc - (:nlink target-inode)))) - :lookup-table (assoc lookup-table nodeid - (assoc children filename - target-nodeid))))))))))) + state)))))))) (unlink [_ nodeid filename continuation!] (send state-agent (fn [state] - (let [lookup-table (:lookup-table state) - inode-table (:inode-table state) - children (get lookup-table nodeid) + (let [inode-table (:inode-table state) + inode (get inode-table nodeid) + children (get-in state [:lookup-table nodeid]) child-nodeid (get children filename) - inode (get inode-table nodeid)] - (if (not (= stat-type-directory - (bit-and stat-type-mask (:mode inode)))) + child-inode (get inode-table child-nodeid)] + (cond + (nil? inode) + (do (continuation! errno-noent) state) + (not (= stat-type-directory + (bit-and stat-type-mask (:mode inode)))) (do (continuation! errno-notdir) state) - (if (nil? child-nodeid) - (do (continuation! errno-noent) state) - (let [child-inode (get inode-table child-nodeid)] - (if (= stat-type-directory - (bit-and stat-type-mask (:mode child-inode))) - (do (continuation! errno-isdir) state) - (let [nlink (dec (:nlink child-inode))] - (continuation! 0) - (assoc state - :lookup-table (assoc lookup-table nodeid - (dissoc children filename)) - :inode-table (if (zero? nlink) - (dissoc inode-table child-nodeid) - (assoc - inode-table child-nodeid - (assoc child-inode - :nlink nlink))))))))))))) + (nil? child-inode) + (do (continuation! errno-noent) state) + (= stat-type-directory + (bit-and stat-type-mask (:mode child-inode))) + (do (continuation! errno-isdir) state) + true + (let [nlink (dec (:nlink child-inode)) + state (assoc-in state [:lookup-table nodeid] + (dissoc children filename)) + inode-table (if (zero? nlink) + (dissoc inode-table child-nodeid) + (assoc-in inode-table [child-nodeid :nlink] + nlink)) + state (assoc state :inode-table inode-table)] + ;; agent-do? + (continuation! 0) + state)))))) (rmdir [_ nodeid filename continuation!] (send state-agent (fn [state] - (let [lookup-table (:lookup-table state) - inode-table (:inode-table state) + (let [inode-table (:inode-table state) + inode (get inode-table nodeid) + lookup-table (:lookup-table state) children (get lookup-table nodeid) child-nodeid (get children filename) - inode (get inode-table nodeid)] - (if (not (= stat-type-directory - (bit-and stat-type-mask (:mode inode)))) + child-inode (get inode-table child-nodeid) + child-children (get lookup-table child-nodeid)] + (cond + (nil? inode) + (do (continuation! errno-noent) state) + (not (= stat-type-directory + (bit-and stat-type-mask (:mode inode)))) + (do (continuation! errno-notdir) state) + (nil? child-nodeid) + (do (continuation! errno-noent) state) + (not (= stat-type-directory + (bit-and stat-type-mask (:mode child-inode)))) (do (continuation! errno-notdir) state) - (if (nil? child-nodeid) - (do (continuation! errno-noent) state) - (let [child-inode (get inode-table child-nodeid) - child-children (get lookup-table child-nodeid)] - (if (not (= stat-type-directory - (bit-and stat-type-mask (:mode child-inode)))) - (do (continuation! errno-notdir) state) - (if (not (empty? (dissoc child-children "." ".."))) - (do (continuation! errno-notempty) state) - ;; TODO: 3 is wrong if . or .. don't exist - (let [nlink (- (:nlink child-inode) 3)] - (agent-do state-agent (continuation! 0)) - (assoc state - :lookup-table (dissoc - (assoc lookup-table nodeid - (dissoc children filename)) - child-nodeid) - :inode-table (if (zero? nlink) - (dissoc inode-table child-nodeid) - (assoc - inode-table child-nodeid - (assoc child-inode - :nlink nlink)))))))))))))) + (not (empty? (dissoc child-children "." ".."))) + (do (continuation! errno-notempty) state) + true + ;; TODO: 3 is wrong if . or .. don't exist + ;; and we need to (dec (:nlink inode)) + (let [nlink (- (:nlink child-inode) 3) + lookup-table (assoc lookup-table nodeid + (dissoc children filename)) + lookup-table (dissoc lookup-table child-nodeid) + state (assoc state :lookup-table lookup-table) + inode-table (if (zero? nlink) + (dissoc inode-table child-nodeid) + (assoc-in inode-table [child-nodeid :nlink] + nlink)) + state (assoc state :inode-table inode-table)] + (agent-do state-agent (continuation! 0)) + state)))))) (chmod [_ nodeid mode continuation!] (attribute-modifier! state-agent nodeid #(bit-or (bit-and stat-type-mask %) @@ -240,20 +236,14 @@ (send state-agent (fn [state] - (let [inode-table (:inode-table state) - file-table (:file-table state) - file (get file-table nodeid)] - (if (contains? inode-table nodeid) - (do - (agent-do state-agent (continuation! nil)) - (assoc - state - :inode-table (assoc-deep inode-table size nodeid :size) - :file-table (assoc - file-table nodeid - (take size - (concat file (repeat (byte 0))))))) - (do (continuation! errno-noent) state)))))) + (if (nil? (get-in state [:inode-table nodeid])) + (do (continuation! errno-noent) state) + (let [file (get-in state [:file-table nodeid]) + state (assoc-in state [:inode-table nodeid :size] size) + state (assoc-in state [:file-table nodeid] + (take size (concat file (repeat (byte 0)))))] + (agent-do state-agent (continuation! nil)) + state))))) (setatime [_ nodeid seconds nseconds continuation!] (inode-modifier! state-agent nodeid #(assoc % :atime seconds :atimensec nseconds) diff --git a/src/clojure/foofs/util.clj b/src/clojure/foofs/util.clj index 6375848..04f2d90 100644 --- a/src/clojure/foofs/util.clj +++ b/src/clojure/foofs/util.clj @@ -15,14 +15,6 @@ (ns foofs.util) -;; TODO: replace this with assoc-in -(defn assoc-deep - "Associates val with the 'path' of keys in a nested map." - [_map _val _key & _keys] - (if (nil? _keys) - (assoc _map _key _val) - (assoc _map _key (apply assoc-deep (get _map _key) _val _keys)))) - (defn next-key [_map _key _min _max] (first (remove (partial contains? _map) (concat (range _key _max) |