You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently solod does not have directives about using packed and bitfield on struct. I hope that there will be such two directive annotations, which can be used like this: .
Thank you! I can't promise these, but I'll look into it while working on v0.2. Do you have a specific use case for these structures (sdshdr16 and node), or are they just examples?
I am rewriting resis 8/valkey 9 using solod. These are all real data structures:
struct __attribute__((__packed__)) sdshdr5 {
unsigned charflags; /* 3 lsb of type, and 5 msb of string length */charbuf[];
};
struct __attribute__((__packed__)) sdshdr8 {
uint8_tlen; /* used */uint8_talloc; /* excluding the header and null terminator */unsigned charflags; /* 3 lsb of type, 5 unused bits */charbuf[];
};
struct __attribute__((__packed__)) sdshdr16 {
uint16_tlen; /* used */uint16_talloc; /* excluding the header and null terminator */unsigned charflags; /* 3 lsb of type, 5 unused bits */charbuf[];
};
struct __attribute__((__packed__)) sdshdr32 {
uint32_tlen; /* used */uint32_talloc; /* excluding the header and null terminator */unsigned charflags; /* 3 lsb of type, 5 unused bits */charbuf[];
};
struct __attribute__((__packed__)) sdshdr64 {
uint64_tlen; /* used */uint64_talloc; /* excluding the header and null terminator */unsigned charflags; /* 3 lsb of type, 5 unused bits */charbuf[];
};
typedefstructquicklistNode {
structquicklistNode*prev;
structquicklistNode*next;
unsigned char*entry;
size_tsz; /* entry size in bytes */unsigned intcount : 16; /* count of items in listpack */unsigned intencoding : 2; /* RAW==1 or LZF==2 */unsigned intcontainer : 2; /* PLAIN==1 or PACKED==2 */unsigned intrecompress : 1; /* was this node previous compressed? */unsigned intattempted_compress : 1; /* node can't compress; too small */unsigned intdont_compress : 1; /* prevent compression of entry that will be used later */unsigned intextra : 9; /* more bits to steal for future usage */
} quicklistNode;
Due to the lack of packed, I use []byte to achieve this. For the absence of bitfield, I use a single uint32 field to partition it as 16 + 2 + 2 + 1 + 1 + 1 + 9 bits. The code readability is not good as the C language version.
go install solod.dev/cmd/so@600e881fe72c
go get solod.dev@600e881fe72c
But honestly, I doubt that porting something as big as Redis to So makes much sense. It's probably better to just write some bindings and call it, instead of porting the whole thing.
I am implementing Redis using Solod in order to deeply understand it, and the best way to deeply understand it is to re-implement it in another language. I have previously implemented the standalone version of Redis 5 in Zig, but the experience was not enjoyable—it was too verbose, function parameters can not be reassigned, and goto was removed from the language. A few days ago, I looked into Odin; it is largely good, but lacks goto. I have always believed that an excellent systems programming language should have simple syntax and come with a rich standard library. As a Go developer, I appreciate Go’s design philosophy. Solod is exactly that kind of language—a pragmatic language I have been looking for for years.
Very thank you for your hard working!
Reacted by Toni DY
Reacted by Pierre Curto, Anton Zhiyanov, david, pourfar, Ardit Marku and Toni DY
Wow, this is really impressive! I once thought about porting Redis to Go, but after looking through the source code, I realized it would be way too much work.
It is difficult to implement AOF rewriting and RDB generation in Go. To obtain a memory snapshot, AOF rewriting and RDB generation need to be run in a subprocess. Even if the subprocess is forcibly forked, the GC is modifying memory at every moment, COW is happening in the kernel at all times, memory usage spikes, and the point of reimplementation is completely lost. If these two tasks were done within a sub-goroutine, the data structure would need to implement MVCC, making it very difficult and requiring high memory consumption. So you can imagine how happy I was to see Solod!
Reacted by Anton Zhiyanov, david, Ardit Marku and Toni DY
Activity
nalgeon commentedon May 7, 2026
Thank you! I can't promise these, but I'll look into it while working on v0.2. Do you have a specific use case for these structures (
sdshdr16andnode), or are they just examples?fanpei91 commentedon May 7, 2026
I am rewriting resis 8/valkey 9 using solod. These are all real data structures:
Due to the lack of packed, I use []byte to achieve this. For the absence of bitfield, I use a single uint32 field to partition it as 16 + 2 + 2 + 1 + 1 + 1 + 9 bits. The code readability is not good as the C language version.
nalgeon commentedon May 7, 2026
I see, thanks for explaining!
fanpei91 commentedon May 7, 2026
Regarding the bitfield feature, if future support is planned, an approach like the following may be a choice:
[-]support packed and bitfield annotations[/-][+]Packed and bitfield annotations[/+]nalgeon commentedon May 7, 2026
Starting with 600e881, you can use the
so:attrdirective to add GCC attributes:To install the latest version:
But honestly, I doubt that porting something as big as Redis to So makes much sense. It's probably better to just write some bindings and call it, instead of porting the whole thing.
fanpei91 commentedon May 8, 2026
Nice! Smart design!
I am implementing Redis using Solod in order to deeply understand it, and the best way to deeply understand it is to re-implement it in another language. I have previously implemented the standalone version of Redis 5 in Zig, but the experience was not enjoyable—it was too verbose, function parameters can not be reassigned, and
gotowas removed from the language. A few days ago, I looked into Odin; it is largely good, but lacksgoto. I have always believed that an excellent systems programming language should have simple syntax and come with a rich standard library. As a Go developer, I appreciate Go’s design philosophy. Solod is exactly that kind of language—a pragmatic language I have been looking for for years.Very thank you for your hard working!
nalgeon commentedon May 8, 2026
Wow, this is really impressive! I once thought about porting Redis to Go, but after looking through the source code, I realized it would be way too much work.
Thank you!
fanpei91 commentedon May 8, 2026
It is difficult to implement AOF rewriting and RDB generation in Go. To obtain a memory snapshot, AOF rewriting and RDB generation need to be run in a subprocess. Even if the subprocess is forcibly forked, the GC is modifying memory at every moment, COW is happening in the kernel at all times, memory usage spikes, and the point of reimplementation is completely lost. If these two tasks were done within a sub-goroutine, the data structure would need to implement MVCC, making it very difficult and requiring high memory consumption. So you can imagine how happy I was to see Solod!