Simple binary vector format reader
Reads the vecs family of binary vector formats (e.g. .bvecs, .ivecs, .fvecs), defined at INRIA LEAR around 2008-2009 and used by the TEXMEX reference datasets.
Supports int8, int16, int32, float32, int64, and float64 elements.
All vectors in the file should be of the same type, but do not have to be of the same dimensions.
Each vector should be of the form:
[length][element:0]...[element:length-1]
Where length is an int, and element is one of the supported vector component types.
The file should then be a contiguous array of the above vectors.
[vector][vector][vector]...
For example:
Path path = Path.of("/path/to/vectors.fvecs");
try (CloseableIterator<float[]> vectors = VectorFileIterators.floats(path)) {
while (vectors.hasNext()) {
float[] vector = vectors.next();
// process vector
}
} catch (IOException exception) {
// handle exception
}
Composable API
VectorFileIterators is a thin convenience over a composable API with sensible defaults. For control over where the bytes come from, how they are buffered, and their byte order, compose a reader from a source, a buffering strategy, and the element type:
Path path = Path.of("/path/to/vectors.bvecs");
try (CloseableIterator<short[]> vectors = VectorReader.from(Source.file(path)) // read from a file
.fixed(Buffers.heap(1 << 20)) // 1 MiB read-ahead buffer
.as(ElementType.INT8) // of 8-bit vectors
.map(VectorConverters::unsignedBytesToShorts) // interpreted as unsigned
.filter(vector -> vector.length == 128) // keeping only 128d vectors
.limit(10_000_000)) { // but only the first 10M
while (vectors.hasNext()) {
short[] vector = vectors.next();
// process vector
}
} catch (IOException exception) {
// handle exception
}
- Source
- where the bytes come from:
Source.file(path),Source.directFile(path)(direct IO),Source.stream(inputStream),Source.channel(channel), orSource.bytes(array). - Buffering
fixed(Buffers.heap(capacity))reads ahead into one shared buffer, whilegrowable(order)reads each record exactly into a buffer that grows as records require.Buffers.heap(capacity, order)sets the byte order;Buffers.direct(capacity, order)allocates a block-aligned direct buffer for use withSource.directFile.- Type
as(type)names the element type the file was written with, one ofElementType.INT8,INT16,INT32,FLOAT32,INT64, orFLOAT64. No format records its own element type, so naming the wrong one decodes into meaningless values. The namedbytes(),shorts(),ints(),longs(),floats(), anddoubles()are deprecated since 1.1.0.- Operations
- the returned
CloseableIteratoris lazy - chainfilter,map,peek,limit,skip,takeWhile, ordropWhile. Each returns aCloseableIterator, so a try-with-resources on the final link still closes the source.
VectorConverterssupplies element mappers formap, such as unsigned widenings (unsignedBytesToShorts) and the...ToFloatsnarrowings.
