Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

new data structure to speed up multipart forms and file uploads

Uploads now seem to be 4x faster.
  • Loading branch information...
commit 16173ec1ffe4c72d738fec863c7882eebc2a361b 1 parent 1882b3b
@akkartik akkartik authored
View
5 arc.arc
@@ -329,6 +329,11 @@
(> n 0) (nthcdr (- n 1) (cdr xs))
xs))
+(def lastcdr (xs)
+ (if cdr.xs
+ (lastcdr cdr.xs)
+ xs))
+
; Generalization of pair: (tuples x) = (pair x)
(def tuples (xs (o n 2))
View
59 lib/spliceable-list.arc
@@ -0,0 +1,59 @@
+;; append elems to it, check n-elem suffix for a match, then splice the suffix out
+
+(def spliceable-list (n (o init))
+ ++.n
+ (annotate 'spliceable-list (obj contents init
+ last lastcdr.init
+ suffix-len n
+ suffix (suffix n init))))
+
+(defmethod len(l) spliceable-list
+ (len rep.l!contents))
+
+(defmethod empty(l) spliceable-list
+ (empty rep.l!contents))
+
+(defgeneric append(a b)
+ (= (cdr lastcdr.a) b))
+
+(defmethod append(l tail) spliceable-list
+ (if empty.l
+ (= rep.l!contents tail
+ rep.l!last rep.tail)
+ (= (cdr rep.l!last) tail))
+ (zap lastcdr rep.l!last)
+ (if rep.l!suffix
+ (zap [nthcdr len.tail _] rep.l!suffix)
+ (= rep.l!suffix
+ (suffix rep.l!suffix-len
+ rep.l!contents))))
+
+(defcoerce cons spliceable-list (l)
+ rep.l!contents)
+
+(defcoerce spliceable-list cons (l)
+ (spliceable-list l))
+
+(defcall spliceable-list (l i)
+ rep.l!contents.i)
+
+(extend sref (l v i) (isa l 'spliceable-list)
+ (sref rep.l!contents v i))
+
+; returns all but the suffix; corrupts the suffix list
+(def splice(l)
+ (when rep.l!suffix
+ (wipe (cdr rep.l!suffix))
+ rep.l!contents))
+
+(defgeneric suffix (n l)
+ (let max len.l
+ (if (> max n)
+ (nthcdr (- max n) l))))
+
+(defmethod suffix (l) spliceable-list
+ (aif rep.l!suffix
+ cdr.it
+ (if (iso rep.l!suffix-len (len rep.l!contents))
+ (cdr rep.l!contents)
+ rep.l!contents)))
View
38 lib/spliceable-list.arc.t
@@ -0,0 +1,38 @@
+(test-iso "spliceable-list initializes without a list"
+ (obj contents nil last nil suffix-len 3 suffix nil)
+ (rep:spliceable-list 2))
+
+(test-iso "spliceable-list initializes with a list"
+ (obj contents list.1 last list.1 suffix-len 3 suffix nil)
+ (rep:spliceable-list 2 '(1)))
+
+(= l (spliceable-list 2 '(1)))
+(test-iso "suffix 1" '(1) suffix.l)
+
+(append l list.2)
+(test-iso "suffix 2" '(1 2) suffix.l)
+(test-iso "appending to spliceable-list works"
+ (obj contents '(1 2) last list.2 suffix nil suffix-len 3)
+ rep.l)
+
+(append l list.3)
+(test-iso "suffix 3" '(2 3) suffix.l)
+(test-iso "splicing a list without a suffix works"
+ nil
+ splice.l)
+
+(= l (spliceable-list 2 '(1 2 3)))
+(test-iso "splicing a list about to get a suffix currently returns nothing"
+ nil ; should be '(1)
+ splice.l)
+
+(= l (spliceable-list 2 '(1 2 3)))
+(append l list.4)
+(test-iso "suffix 4" '(3 4) suffix.l)
+(test-iso "appending to spliceable-list updates suffix"
+ (obj contents '(1 2 3 4) last list.4 suffix '(2 3 4) suffix-len 3)
+ rep.l)
+
+(test-iso "splicing a list with suffix works"
+ '(1 2)
+ splice.l)
View
10 lib/srv.arc
@@ -313,11 +313,11 @@ Connection: close"))
; pat is read from input but dropped from result
; all chars in pat must be 1-byte
(def scan-past(pat in)
- (= pat (map int (rev:coerce pat 'cons)))
- (let buffer nil
- (until (iso pat (firstn len.pat buffer))
- (push readb.in buffer))
- (rev:nthcdr len.pat buffer)))
+ (= pat (map int (coerce pat 'cons)))
+ (let buffer (spliceable-list len.pat)
+ (until (iso pat suffix.buffer)
+ (append buffer (list readb.in)))
+ splice.buffer))
; convert list of bytes to string
(def bytes-string(l)
View
1  libs.arc
@@ -2,6 +2,7 @@
"lib/extend.arc"
"lib/strings.arc"
"lib/queue.arc"
+ "lib/spliceable-list.arc"
"lib/tem.arc"
"lib/util.arc"
"lib/declare.arc"
Please sign in to comment.
Something went wrong with that request. Please try again.