src/Pure/General/buffer.ML
author wenzelm
Wed, 21 Aug 2019 17:32:44 +0200
changeset 70601 79831e40e2be
parent 70600 6e97e31933a6
child 70998 7926d2fc3c4c
permissions -rw-r--r--
more scalable: avoid huge intermediate XML elems;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6316
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
     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
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
     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
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
     5
*)
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
     6
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
     7
signature BUFFER =
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
     8
sig
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
     9
  type T
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
    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
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
    14
  val add: string -> T -> T
23785
ea7c2ee8a47a added markup operation;
wenzelm
parents: 23226
diff changeset
    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
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
    17
end;
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
    18
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
    19
structure Buffer: BUFFER =
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
    20
struct
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
    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
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
    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
7272b45099c7 tuned Buffer.add;
wenzelm
parents: 16712
diff changeset
    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
7272b45099c7 tuned Buffer.add;
wenzelm
parents: 16712
diff changeset
    56
23785
ea7c2ee8a47a added markup operation;
wenzelm
parents: 23226
diff changeset
    57
fun markup m body =
ea7c2ee8a47a added markup operation;
wenzelm
parents: 23226
diff changeset
    58
  let val (bg, en) = Markup.output m
ea7c2ee8a47a added markup operation;
wenzelm
parents: 23226
diff changeset
    59
  in add bg #> body #> add en end;
ea7c2ee8a47a added markup operation;
wenzelm
parents: 23226
diff changeset
    60
68228
326f4bcc5abc more scalable;
wenzelm
parents: 60982
diff changeset
    61
fun output buf stream =
326f4bcc5abc more scalable;
wenzelm
parents: 60982
diff changeset
    62
  List.app (fn s => BinIO.output (stream, Byte.stringToBytes s)) (chunks buf);
26502
7f64d8cf6707 added add_substring;
wenzelm
parents: 23785
diff changeset
    63
6316
4a786a8a1a97 simple string buffers;
wenzelm
parents:
diff changeset
    64
end;