Skip to content

Commit e6eb8d6

Browse files
authored
Merge pull request #21 from inhabitedtype/allocation
allocation: be better about allocating a new buffer for writes
2 parents b5eb8da + 38f42a8 commit e6eb8d6

File tree

2 files changed

+23
-20
lines changed

2 files changed

+23
-20
lines changed

lib/faraday.ml

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,7 @@ let flush_buffer t =
206206
if len > 0 then begin
207207
let off = t.scheduled_pos in
208208
schedule_iovec t ~off ~len (`Bigstring t.buffer);
209-
t.buffer <- Bigarray.(Array1.create char c_layout (Array1.dim t.buffer));
210-
t.write_pos <- 0;
211-
t.scheduled_pos <- 0
209+
t.scheduled_pos <- t.write_pos
212210
end
213211

214212
let flush t f =
@@ -267,13 +265,13 @@ let schedule_bigstring =
267265
fun t ?off ?len a -> schedule_gen t ~length ~to_buffer ?off ?len a
268266

269267
let ensure_space t len =
270-
if free_bytes_in_buffer t < len then (
268+
if free_bytes_in_buffer t < len then begin
271269
flush_buffer t;
272-
`Not_enough_space
273-
)
274-
else (
275-
`Go_ahead
276-
)
270+
t.buffer <-
271+
Bigarray.(Array1.create char c_layout (max (Array1.dim t.buffer) len));
272+
t.write_pos <- 0;
273+
t.scheduled_pos <- 0
274+
end
277275

278276
let write_gen t ~length ~blit ?(off=0) ?len a =
279277
writable t;
@@ -282,14 +280,9 @@ let write_gen t ~length ~blit ?(off=0) ?len a =
282280
| None -> length a - off
283281
| Some len -> len
284282
in
285-
match ensure_space t len with
286-
| `Not_enough_space ->
287-
let buffer = Bigarray.(Array1.create char c_layout len) in
288-
blit a off buffer 0 len;
289-
schedule_iovec t ~len (`Bigstring buffer)
290-
| `Go_ahead ->
291-
blit a off t.buffer t.write_pos len;
292-
t.write_pos <- t.write_pos + len
283+
ensure_space t len;
284+
blit a off t.buffer t.write_pos len;
285+
t.write_pos <- t.write_pos + len
293286

294287
let write_string =
295288
let length = String.length in
@@ -421,8 +414,10 @@ let rec shift_buffers t written =
421414
Buffers.enqueue_front (IOVec.shift iovec written) t.scheduled
422415
with Not_found ->
423416
assert (written = 0);
424-
t.scheduled_pos <- 0;
425-
t.write_pos <- 0
417+
if t.scheduled_pos = t.write_pos then begin
418+
t.scheduled_pos <- 0;
419+
t.write_pos <- 0
420+
end
426421

427422
let rec shift_flushes t =
428423
try

lib_test/test_faraday.ml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ let write_tiny_buf =
5858
check ~buf_size:1 ~iovecs:1 ~msg:"string" [`Write_string "test"] "test";
5959
check ~buf_size:1 ~iovecs:1 ~msg:"bytes" [`Write_bytes "test"] "test";
6060
check ~buf_size:1 ~iovecs:1 ~msg:"bigstring" [`Write_bigstring "test"] "test"
61+
end
62+
; "multiple writes with tiny buffer", `Quick, begin fun () ->
63+
check ~buf_size:1 ~iovecs:2 ~msg:"string" [`Write_string "test1"; `Write_string "test2"] "test1test2"
64+
end
65+
; "too many writes with tiny buffer", `Quick, begin fun () ->
66+
check ~buf_size:1 ~iovecs:5 ~msg:"string"
67+
[`Write_string "te"; `Write_string "st"; `Write_string "te"; `Write_string "st"; `Write_string "te" ]
68+
"testtestte"
6169
end ]
6270

6371
let schedule =
@@ -101,6 +109,6 @@ let () =
101109
Alcotest.run "test suite"
102110
[ "empty output" , empty
103111
; "single write" , write
104-
; "single write (tiny buffer)", write
112+
; "writes (tiny buffer)" , write_tiny_buf
105113
; "single schedule" , schedule
106114
; "interleaved calls" , interleaved ]

0 commit comments

Comments
 (0)