Foundation · The collections beneath everything
Invercargill
The Enumerable library for Vala — LINQ-style querying plus the data structures the whole Astrologue stack is written against. Every row a database returns, every setting a server reads, every key a cryptographer signs passes through this library.
- Version
1.0.0- Licence
- LGPL-3.0-or-later
- Package
usm install invercargill- Language
- Vala
Overview
Why it exists
Invercargill is a comprehensive data-manipulation library for the Vala programming language. Its central Enumerable<T> type makes working with data sets significantly more intuitive and less cognitively taxing, with a rich set of functional-programming tools for transformation, querying and manipulation.
It exists because its author — a C# developer by trade — kept missing the operations the .NET IEnumerable interface provides. Unwilling to settle for LibGee, he rolled a library of his own and named it after New Zealand's southernmost city. It takes heavy inspiration from C#'s interface, adapted where Vala's nuances call for it, and adds unique functions and structures of its own.
Today it is the foundation of the Astrologue stack: the query results of Invercargill-Sql arrive as lazy Enumerable rows, Inversion resolves its registrations through it, and every library above leans on its data structures instead of GLib.ArrayList or LibGee.
Features
What it hands you
- Enumerable everywhere. One interface for iteration, transformation, filtering, aggregation, set operations, ordering, partitioning and grouping — chained fluently.
- Data structures. Vector, Series, SortedSeries, Dictionary, HashSet, Buffer, ByteBuffer, RingBuffer, PriorityQueue, Fifo and Lifo, each with a job.
- Lazy evaluation. Sequences are computed as they are walked, with caching mechanisms for when a second pass should not recompute.
- Parallel processing. Built-in parallel operations to leverage multi-core processors.
- Numbers as sequences. Promotions turn an
Enumerable<int>into a numeric view withsum(),average()and friends. - Attempts. Safe operation handling with error recovery, so a fallible step can be retried or abandoned without ceremony.
Installation
Getting the library
With USM on your machine, one command acquires, builds and installs the library together with its C header, Vala binding and introspection:
usm install invercargill
From source, the library follows the stack's one-build discipline:
git clone <the Invercargill repository>
cd Invercargill
meson setup src build
ninja -C build
ninja -C build install
src/; the README and the package scripts agree on it.Then compile against it with Vala's usual package mechanism:
valac --pkg invercargill-1 my-program.vala
-1 suffix keeps the ABI generation honest.Usage & documentation
Working with sequences
Wrap anything enumerable — an array, a generic array, a stream — and work with it through the fluent API. These idioms are lifted from the library's own integration tests:
using Invercargill;
var items = Wrap.array(new int[] { 1, 2, 3, 4, 5 });
var result = items.aggregate<int>(0, (sum, item) => sum + item);
// result == 15
var words = Wrap.array(new string[] { "Hello", " ", "World", "!" });
var greeting = words.aggregate<string>("", (concat, item) => concat + item);
// greeting == "Hello World!"
src/tests/Integration/EnumerableMethods.vala — aggregate folds a sequence down to one value.Predicates come in matched pairs, and empty sequences answer honestly:
var evens = Wrap.array(new int[] { 2, 4, 6, 8 });
evens.all(i => i % 2 == 0); // true
evens.any(i => i == 5); // false
evens.no(i => i % 2 == 1); // true — nothing matches
var empty = Wrap.array(new int[] {});
empty.any(); // false
empty.no(); // true
all, any and no — the last is the existential negative LibGee never gave Vala.Ordering and projection compose like their C# cousins:
var items = ClassToOrder.data();
var result = items.order_by<int>(i => i.id);
var ids = result.select<int>(i => i.id);
var newest_first = items.order_by_descending<string>(i => i.name);
src/tests/Integration/OrderBy.vala.The modifier vocabulary goes much further — where(), from(), until() for filtering; select(), select_many(), cast(), of_type() for transformation; combine(), common(), exclude(), distinct() for set operations; take(), skip(), chunk(), window() for partitioning; and zip(), concat(), interleave(), cycle() for combination.
The data structures
Alongside the query layer sit the collections the stack is actually written with — used in place of GLib.ArrayList, GLib.List and GLib.HashTable:
using Invercargill.DataStructures;
var data = new Vector<int>();
data.add(5);
data.add(15);
data.add(10);
var numbers = data.assert_promotion<SignedNativeIntegers>();
var mean = numbers.average(); // 10
var dict = new Dictionary<int, string>();
dict[1999] = "Billy";
dict[1962] = "John";
string? billy = dict.get_or_default(1999);
src/tests/Integration/Numbers.vala and Dictionary.vala. A promotion turns a plain sequence into a numeric view.The full set: Vector (dynamic array), Series (linked list, efficient at both ends), SortedSeries (red-black tree, kept in order), Dictionary (key-value store), HashSet (hash table with tombstone deletion), Buffer and ByteBuffer, ImmutableBuffer, RingBuffer (circular, iterable forever), PriorityQueue (min-heap, thread-safe push/pop), and Fifo/Lifo (thread-safe queue and stack with blocking operations and unblocking support).
The library also carries an expressions subsystem, property mapping, debugging utilities and the promotion system shown above. Its test suite — integration and speed — runs through meson test and through USM's test exec, so what is documented here is what is exercised.
Package & source
The ledger
- Version
1.0.0(fromMANIFEST.usm)- Licence
- LGPL-3.0-or-later — free to run, study, share and improve; the LGPL keeps it free to link from any program.
- Package
usm install invercargill- Provides
libinvercargill-1.so,invercargill-1.h,invercargill-1.vapi+.deps,invercargill-1.gir,invercargill-1.typelib,invercargill-1.pc- Needs at runtime
- GLib and GObject — nothing else. The foundation carries no dependencies of its own.
- Source
- The repository
Tilo15/Invercargillon the Astrologue forge (git over ssh, port 222). Free software: the licence guarantees your right to the source.