From e5e9c8b46c5deb8de9053c5906d0b9f406097816 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 29 Nov 2024 19:32:47 -0500 Subject: [PATCH] Make Int serialization more compact --- README.md | 1 + stdlib/integers.c | 32 +++++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b7b8929..ca61a18 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ of many language features or the other example programs/modules in - [Easy interoperability with C](docs/c-interoperability.md) - Support for [POSIX threads](docs/threads.tm) and thread-safe message passing queues over [channels](docs/channels.tm). +- Built-in data serialization and deserialization for datatypes. ## Dependencies diff --git a/stdlib/integers.c b/stdlib/integers.c index b40657b..cd6492a 100644 --- a/stdlib/integers.c +++ b/stdlib/integers.c @@ -369,19 +369,33 @@ static bool Int$is_none(const void *i, const TypeInfo_t*) return ((Int_t*)i)->small == 0; } -static void Int$serialize(const void *obj, FILE *out, Table_t*, const TypeInfo_t*) +static void Int$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t*) { - mpz_t n; - mpz_init_set_int(n, *(Int_t*)obj); - mpz_out_raw(out, n); + Int_t i = *(Int_t*)obj; + if (__builtin_expect((i.small & 1), 1)) { + fputc(0, out); + int64_t i64 = i.small >> 2; + Int64$serialize(&i64, out, pointers, &Int64$info); + } else { + fputc(1, out); + mpz_t n; + mpz_init_set_int(n, *(Int_t*)obj); + mpz_out_raw(out, n); + } } -static void Int$deserialize(FILE *in, void *obj, Array_t*, const TypeInfo_t*) +static void Int$deserialize(FILE *in, void *obj, Array_t *pointers, const TypeInfo_t*) { - mpz_t n; - mpz_init(n); - mpz_inp_raw(n, in); - *(Int_t*)obj = Int$from_mpz(n); + if (fgetc(in) == 0) { + int64_t i = 0; + Int64$deserialize(in, &i, pointers, &Int64$info); + *(Int_t*)obj = (Int_t){.small=(i<<2) | 1}; + } else { + mpz_t n; + mpz_init(n); + mpz_inp_raw(n, in); + *(Int_t*)obj = Int$from_mpz(n); + } } public const TypeInfo_t Int$info = {