Browse files

Use defrecord and match-type

  • Loading branch information...
1 parent 0980fef commit 8ef552bc7a2ff83d9730c7a7a7c112e39c5ddd91 @jamii committed Apr 8, 2012
Showing with 33 additions and 10 deletions.
  1. +13 −10 src/mist/kademlia/bittree.clj
  2. +20 −0 src/mist/strict.clj
@@ -1,26 +1,29 @@
(ns mist.kademlia.bittree
"A bittree maps bitstrings to buckets and also calculates numbers needed for deciding when to split a bucket. Buckets are opaque to the bittree except that they must implement count."
(:require [mist.kademlia.util :as util]
- [mist.strict :as strict]
- clojure.core.match))
+ [mist.strict :as strict]))
+(defrecord Leaf [bucket size])
+(defrecord Branch [child-t child-f size])
(defn leaf [bucket]
- {:type ::leaf :bucket bucket :size (count bucket)})
+ (Leaf. bucket (count bucket)))
(defn branch [child-t child-f]
- {:type ::branch :child-t child-t :child-f child-f :size (+ (:size child-t) (:size child-f))})
+ (Branch. child-t child-f (+ (:size child-t) (:size child-f))))
(defn- update-internal [update-fun target-bits self-bits depth gap tree]
"Note: gap is defined as the total size of all buckets closer to self than target"
- (strict/match [tree]
- [{:type ::leaf :bucket bucket}]
+ (strict/match-type tree
+ [Leaf {:bucket bucket}]
(strict/match [(update-fun target-bits depth gap bucket)]
[[:single new-bucket]] ; update done
(leaf new-bucket)
[[:split new-bucket-t new-bucket-f]] ; have to split first then continue
(let [tree (branch (leaf new-bucket-t) (leaf new-bucket-f))]
(recur update-fun target-bits self-bits depth gap tree)))
- [{:type ::branch :child-t child-t :child-f child-f}]
+ [Branch {:child-t child-t :child-f child-f}]
(let [next-target-bit (first target-bits)
next-self-bit (first self-bits)
target-bits (rest target-bits)
@@ -44,11 +47,11 @@
(update-internal update-fun (util/bits target) (util/bits self) 0 0 tree))
(defn- buckets-internal [prefix-bits suffix-bits tree later-seq]
- (strict/match [tree]
- [{:type ::leaf :bucket bucket}]
+ (strict/match-type tree
+ [Leaf {:bucket bucket}]
(let [next-item [(reverse prefix-bits) bucket]]
(lazy-seq (cons next-item later-seq)))
- [{:type ::branch :child-t child-t :child-f child-f}]
+ [Branch {:child-t child-t :child-f child-f}]
(let [next-bit (first suffix-bits)
suffix-bits (rest suffix-bits)
prefix-bits (cons next-bit prefix-bits)
@@ -8,3 +8,23 @@
:else (let [msg# (str "Could not match " pattern#)]
(throw (new Exception msg#))))))
+(defn unleave [seq]=
+ [(take-nth 2 seq) (take-nth 2 (rest seq))])
+(defn zip [& seqs]
+ (apply map vector seqs))
+(defn unzip [seq]
+ [(map #(nth % 0) seq) (map #(nth % 1) seq)])
+(defmacro match-type [pattern & args]
+ (let [[pattern-pairs branches] (unleave args)
+ [types patterns] (unzip pattern-pairs)
+ types (map #(ns-resolve *ns* %) types)
+ pattern-pairs (zip types patterns)
+ args (interleave pattern-pairs branches)]
+ `(let [pattern# ~pattern]
+ (match
+ [(type pattern#) pattern#]
+ ~@args))))

0 comments on commit 8ef552b

Please sign in to comment.