author | wenzelm |
Wed, 21 Aug 2019 17:32:44 +0200 | |
changeset 70601 | 79831e40e2be |
parent 70600 | 6e97e31933a6 |
child 70998 | 7926d2fc3c4c |
permissions | -rw-r--r-- |
6316 | 1 |
(* Title: Pure/General/buffer.ML |
70600
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
2 |
Author: Makarius |
6316 | 3 |
|
70600
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
4 |
Scalable text buffers. |
6316 | 5 |
*) |
6 |
||
7 |
signature BUFFER = |
|
8 |
sig |
|
9 |
type T |
|
10 |
val empty: T |
|
70601
79831e40e2be
more scalable: avoid huge intermediate XML elems;
wenzelm
parents:
70600
diff
changeset
|
11 |
val is_empty: T -> bool |
70600
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
12 |
val chunks: T -> string list |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
13 |
val content: T -> string |
6316 | 14 |
val add: string -> T -> T |
23785 | 15 |
val markup: Markup.T -> (T -> T) -> T -> T |
60982
67e389f67073
precise BinIO, without newline conversion on Windows;
wenzelm
parents:
29323
diff
changeset
|
16 |
val output: T -> BinIO.outstream -> unit |
6316 | 17 |
end; |
18 |
||
19 |
structure Buffer: BUFFER = |
|
20 |
struct |
|
21 |
||
70600
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
22 |
abstype T = Buffer of {chunk_size: int, chunk: string list, buffer: string list} |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
23 |
with |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
24 |
|
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
25 |
val empty = Buffer {chunk_size = 0, chunk = [], buffer = []}; |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
26 |
|
70601
79831e40e2be
more scalable: avoid huge intermediate XML elems;
wenzelm
parents:
70600
diff
changeset
|
27 |
fun is_empty (Buffer {chunk, buffer, ...}) = null chunk andalso null buffer; |
79831e40e2be
more scalable: avoid huge intermediate XML elems;
wenzelm
parents:
70600
diff
changeset
|
28 |
|
70600
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
29 |
local |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
30 |
val chunk_limit = 4096; |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
31 |
|
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
32 |
fun add_chunk [] buffer = buffer |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
33 |
| add_chunk chunk buffer = implode (rev chunk) :: buffer; |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
34 |
in |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
35 |
|
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
36 |
fun chunks (Buffer {chunk, buffer, ...}) = rev (add_chunk chunk buffer); |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
37 |
|
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
38 |
val content = implode o chunks; |
6316 | 39 |
|
70600
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
40 |
fun add x (buf as Buffer {chunk_size, chunk, buffer}) = |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
41 |
let val n = size x in |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
42 |
if n = 0 then buf |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
43 |
else if n + chunk_size < chunk_limit then |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
44 |
Buffer {chunk_size = n + chunk_size, chunk = x :: chunk, buffer = buffer} |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
45 |
else |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
46 |
Buffer {chunk_size = 0, chunk = [], |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
47 |
buffer = |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
48 |
if n < chunk_limit |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
49 |
then add_chunk (x :: chunk) buffer |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
50 |
else x :: add_chunk chunk buffer} |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
51 |
end; |
17062 | 52 |
|
70600
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
53 |
end; |
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
54 |
|
6e97e31933a6
more scalable buffer: produce compact chunks on the fly, avoid too many small particles that might congest heap management;
wenzelm
parents:
68228
diff
changeset
|
55 |
end; |
17062 | 56 |
|
23785 | 57 |
fun markup m body = |
58 |
let val (bg, en) = Markup.output m |
|
59 |
in add bg #> body #> add en end; |
|
60 |
||
68228 | 61 |
fun output buf stream = |
62 |
List.app (fn s => BinIO.output (stream, Byte.stringToBytes s)) (chunks buf); |
|
26502 | 63 |
|
6316 | 64 |
end; |