Fix longest prefix match

This commit is contained in:
xenia 2020-02-04 17:50:08 -05:00
parent dbc2923b7b
commit d27dd3a5a3
1 changed files with 38 additions and 23 deletions

View File

@ -77,15 +77,22 @@
[setter! (rt-setter bit)] [setter! (rt-setter bit)]
[orig-label (rt-edge-label orig-edge)] [orig-label (rt-edge-label orig-edge)]
[orig-target (rt-edge-target orig-edge)] [orig-target (rt-edge-target orig-edge)]
[new-orig-edge (rt-edge (drop orig-label prefix-len) orig-target)] [new-orig-edge (rt-edge (drop orig-label prefix-len) orig-target)])
[new-insert-edge (rt-edge (drop key prefix-len) (if (= prefix-len (length key))
(let* ([next-bit (list-ref orig-label prefix-len)]
[common-node (rt-node (if next-bit #f new-orig-edge)
(if next-bit new-orig-edge #f)
(updater (failure-result)))]
[common-edge (rt-edge (take key prefix-len) common-node)])
(setter! node common-edge))
(let* ([new-insert-edge (rt-edge (drop key prefix-len)
(rt-node #f #f (updater (failure-result))))] (rt-node #f #f (updater (failure-result))))]
[diff-bit (list-ref key prefix-len)] [diff-bit (list-ref key prefix-len)]
[common-node (rt-node (if diff-bit new-orig-edge new-insert-edge) [common-node (rt-node (if diff-bit new-orig-edge new-insert-edge)
(if diff-bit new-insert-edge new-orig-edge) (if diff-bit new-insert-edge new-orig-edge)
empty-node-data)] empty-node-data)]
[common-edge (rt-edge (take key prefix-len) common-node)]) [common-edge (rt-edge (take key prefix-len) common-node)])
(setter! node common-edge))) (setter! node common-edge)))))
(match (rt-partial-iterate node key) (match (rt-partial-iterate node key)
[(list 'exact node) [(list 'exact node)
(set-rt-node-data! (set-rt-node-data!
@ -124,19 +131,6 @@
[rst (apply append (map flatten-edge (list e1 e2)))]) [rst (apply append (map flatten-edge (list e1 e2)))])
(if (equal? data empty-node-data) rst (cons data rst)))) (if (equal? data empty-node-data) rst (cons data rst))))
; (define test (make-rt))
; (define (test-insert! x)
; (rt-update!
; test
; (map (curry equal? #\1) (string->list x))
; (lambda (_) x)
; (lambda () x)))
; (test-insert! "0001")
; ; (test-insert! "1000")
; ; (test-insert! "1010")
; (test-insert! "0011")
; (test-insert! "0000")
;; RT [Str] -> ;; RT [Str] ->
;; Debug print function that dumps the tree to current-output-port in a vaguely human-readable ;; Debug print function that dumps the tree to current-output-port in a vaguely human-readable
;; format ;; format
@ -150,4 +144,25 @@
(when edge1 (when edge1
(displayln (format "~a edge1 ~a" prefix (rt-edge-label edge1))) (displayln (format "~a edge1 ~a" prefix (rt-edge-label edge1)))
(rt-dump (rt-edge-target edge1) (string-append prefix " ")))) (rt-dump (rt-edge-target edge1) (string-append prefix " "))))
;(rt-dump test)
(define test (make-rt))
(define (str->bl x)
(map (curry equal? #\1) (string->list x)))
(define (test-insert! x)
(rt-update!
test
(str->bl x)
(lambda (_) x)
(lambda () x)))
; (test-insert! "0001")
; (test-insert! "000")
; (test-insert! "0")
; (rt-dump test)
; (rt-partial-iterate test (str->bl "0001"))
; (rt-lookup test (str->bl "0001") (lambda () (error "bad")))
; (test-insert! "0001")
; (test-insert! "1000")
; (test-insert! "1010")
; (test-insert! "0011")
; (test-insert! "0000")