diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-05-01 06:16:28 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-05-01 06:16:28 -0700 |
commit | ae064b0ecc0c699bd5e293eada2ee15dabc506be (patch) | |
tree | 186c39dfd048a86d463626b26fd65c29efc4ba05 /share | |
parent | 62c6be5c35da62c1809b217850c18b1e3abe47f1 (diff) | |
download | txr-ae064b0ecc0c699bd5e293eada2ee15dabc506be.tar.gz txr-ae064b0ecc0c699bd5e293eada2ee15dabc506be.tar.bz2 txr-ae064b0ecc0c699bd5e293eada2ee15dabc506be.zip |
sockets: ipv6 address condensing rewrite.
* share/txr/stdlib/socket.tl (sys:in6addr-condensed-text):
Rewrite with regex based implementation that formats
the number without condensing. This one has better
semantics in that it finds the longest run of 0.0..0
to replace, rather than the leftmost. Ignoring this
semantic difference, it also has better average performance on
pseudo-random addresses, with similar performance on
addresses with long condensable 0's. The original algorithm
has a significantly poorer average case on random addresses,
but better best case on condensable zeros like 1::1.
The new algorithm could improve further with future work to
make regexes faster.
Diffstat (limited to 'share')
-rw-r--r-- | share/txr/stdlib/socket.tl | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/share/txr/stdlib/socket.tl b/share/txr/stdlib/socket.tl index 2571aef1..3236460c 100644 --- a/share/txr/stdlib/socket.tl +++ b/share/txr/stdlib/socket.tl @@ -61,21 +61,19 @@ 'str-inaddr addr) `@a.@b.@c.@d@p`))) + (defun sys:in6addr-condensed-text (numeric-pieces) - (let ((parted [partition-by zerop numeric-pieces])) - (if (or (cdr parted) (nzerop (caar parted))) - (let* ((notyet t) - (texts (window-mappend - 1 nil - (lambda (pre chunk post) - (cond - ((and notyet (zerop (car chunk)) (cdr chunk)) - (zap notyet) - (if (and post pre) '("") '(":"))) - (t (mapcar (op format nil "~x") chunk)))) - parted))) - `@{texts ":"}`) - "::"))) + (let* ((str (cat-str [mapcar (load-time (op fmt "~x")) numeric-pieces] ":")) + (zr (rra #/0(:0)+/ str)) + (lp [pos-max zr : (load-time [callf - to from])]) + (lr [zr lp])) + (when lp + (del [str lr])) + (cond + ((equal "" str) "::") + ((starts-with ":" str) `:@str`) + ((ends-with ":" str) `@str:`) + (t str)))) (defun str-in6addr (addr : port) (let ((str (if (and (<= (width addr) 48) |