Spills

Spills are sequences that spill to disk when they do not fit in memory. They are simply represented by a memory-mapped file, hence they are to be used with type that are flat - that is, they are obtained by combining primitive types, objects and arrays, but do not involve seqs, strings or references to heap memory. In short, you should be able to compute their size statically.

Spills work in two modes:

Usually, one first populates a writable spills, then obtains the corresponding spill from that, and works from there.

An example:

import spills

type Foo = object
  a, b: int
  c: float

initSpills()

var x = writableSpill[Foo]()
for i in 0 .. 1000000:
  x.add(Foo(a: i, b: i + 1, c: i.float))
x.close()

var y = spill(x)
echo y
echo y[1234]

var z = y.map(proc(f: Foo): float = f.c)

echo z1[1234]

y.close()
z.close()

Managing resources

Since spills are associated to files, there are two concerns:

Spills are written to a temporary directory by default. To set this directory and create it, call initSpills(dir). Just calling initSpills() will use a default directory of /tmp/spills.

Every method that creates a new spill object optionally accepts a path parameter. If this parameter is missing, files are created in the temporary directory. At the end, you can call destroySpills() to remove the files generated in this directory. In this way, you can choose which files to persist across sessions, and which ones to remove.

Finally, spills (both simple and writable) have a close method that will unmap the file from memory (respectively, close the associated stream).

Sequence operations

Spills admit a few standard sequence operations. Other than reading and writing single items, there are map, filter, foldl and foldr. These work as the similar operations in sequtils, except that map and filter optionally take a path parameter.

There are also functions toSpill[T](s: seq[T]): Spill[T] and toSeq[T](s: Spill[T]): seq[T] to convert back and forth from sequences.

Strings

Strings are variable-length, and as such cannot be stored into spills. Since they are quite a common type, we provide a VarChar[N] type under spills/varchar.

VarChar[N] is a wrapper over an array of N chars and a length field. If you know beforehand that all your strings will not be longer than N, you can use it instead. One can convert back and forth using

import spills/varchar

let
  a = "Hello, world"
  b = a.varchar(15)
  c = $b

assert a == c