> use a GeneralPurposeAllocator and setting "enable_memory_limit" and "requested_memory_limit"
Interesting! I hadn't looked at GeneralPurposeAllocator too closely, but yes these seem like the right way to do things instead of abusing FixedBufferAllocator as I did.
> If the purpose is to "only use the stack"...
Not really, I just had to decide on some arbitrary upper bound on the mem usage, and the default stack size (8MiB) seemed like a decent choice. In retrospect, this challenge only took shape because my solution to Day1 used a FixedBufferAllocator backed by a buffer on the stack, and I realized how easy Zig made it to track allocs. I didn't fiddle too much with the general structure of the solution after that, and made it a "challenge" to see how far I could take it.
> Another potential challenge is to pre-allocate instead
Ah, that sounds much more difficult. This is also what TigerBeetle is doing [1]. But one thing I didn't understand even from that post, how would one deal with data structures that really depend on the input data, like the hashsets in TFA?
Simplest way I can think of is to have an arbitrary upperbound on the allocated memory and then keep checking before every operation on any dynamic structure. That sounds tedious. Is there a better way?
I think you might be able to abuse an ArenaAllocator wrapping a FixedBufferAllocator. I haven't tested it, but IIRC, Zig's ArenaAllocator deallocates in reverse order once it's reset (it uses a singly linked list to keep track of allocations, so that's the natural way to do deallocation), so it might play nicely with the underlying FixedBufferAllocator's requirements.
If this is correct, it's likely an undocumented implementation detail, so probably not something you should rely on always being the case.
>The entire embedded software engineering field is an example.
This is simply false. Most devices are moving in this direction. Practically all phones people use are using a kernel that supports virtual memory. TVs now come with Linux too. All sorts of random devices use Linux now that powerful and cheap chips exist.
> TigerBeetle writes to disk for long-term storage
But how does it determine when it should write to disk? Does every write to a potentially OOM operation get preceeded by a check?
Take the case of a HashAggregate. The DB clearly cannot know at compile time how many unique keys will be present in the hashtable; it needs to resize at runtime. So does that mean all the hashtables are still using some form of Bump/Arena allocators backed by the pre-allocated memory?
> But how does it determine when it should write to disk?
You write fixed sized number of key-value pairs to the file at a time. This is how LSM trees work, you chunk your data up into N sorted keys per chunk. I don't myself understand all the specifics but this is the gist.
> Does every write to a potentially OOM operation get preceeded by a check?
If you allocate memory upfront and don't allocate any more memory, you can't OOM after the initial allocation. That's what TigerBeetle does.
Zig has some nice standard library containers for adding items while asserting that there's capacity. If we miscalculate, it is caught during tests because assertions fail.
Such linear allocators are not too uncommon in embedded / static allocation context, but one definitely needs to know how they work. So first thought was you didn't read the docs, but docs do not clearly state that behavoour that is ugly (:
> So first thought was you didn't read the docs, but docs do not clearly state that behavoour that is ugly (:
Yep, neither the name nor what little documentation there is a are really helpful, and that looks to be a long-standing issue (https://github.com/ziglang/zig/issues/3049).
Seems to me like this allocator should be renamed something like "FixedBufferBumpAllocator", which:
- leaves room for other fixed-buffer allocators (e.g. bitmap, slabs)
- spell out that there's something of note about the allocator, whose drawbacks the developer either would already be aware of or would be able to look up easily
Personally, I still prefer the user style over Github's solution. I find the official black theme has too much contrast (it was probably made for amoled), and the bluish-black variant looks ugly to me. The user style has very good greys, and as a bonus, I've fallen in love with the cross-hatch pattern background it provides.
Just in case you didn't know, since the SolarWinds debacle from last year, Microsoft has completely blocked authorisation for corpnet and other tools on anything other than enrolled devices. And since they only support managed devices on Windows/MacOS, using Linux for day job is a no go. Last I checked, circa Jan, I couldn't use Teams/Office on a web browser in Linux (of course, this might have changed in the meantime).
Yes, I know. I keep my work machines separate (always have, by personal policy), so I never had to deal with that. But the auth limitations and general feature gaps have always prevented me from even thinking about trying, and are more representative than specific policies.
> the problem I have is that sometimes the devices lose sync with each other if they've been off for any length of time. Opening the KDE Connect settings typically fixes this, but it's not ideal!
A slightly better solution I have found helpful is to pull down Yakuake (or krunner) and run `kdeconnect-cli --refresh`. Beats having to open a QT window, only to be closed off immediately.
They have come up with a workaround for this. Instead of actively monitoring your clipboard in the background, there now exists a "Send Clipboard" button/intent that shares the current clipboard value with the other device(s). Works well enough for me on Android 11.
I'm someone who always tries to use the "right tool for the job", CLion for C/C++ (large projects), VSC for Rust (the inline type hints from Rust Analyzer are to die for), and ST for Python.
I tried out the python experience in VSC but have found it to be _inferior_ to the speed of ST when coupled with the Anaconda (not the venv stack) plugin [0]. It supports venvs, build systems (even remote jobs, but I haven't messed around with those), and all the basic things like go to definition (instant! Even works inside libraries) and find usages work quite well. When paired with the SublimeREPL plugin, I get the venv repl inside ST _with_ autocomplete. That is just a step below full blown (slower) Jupyter notebook experience. The Python exception tracebacks in the output panel have their file paths clickable, so I can immediately jump to the source line. This is adequate for me in terms of debugging experience, but ST obviously doesn't bundle a full-fledged debugger like VSC.
The quality of autocomplete is pretty much the same as VSC since both Anaconda and the LSP server use Jedi internally for all the core stuff. There are definitely some rough edges, like having to set the python interpreter path for a new project using venvs, instead of the auto-setup we see in VSC. Another thing is the development of Anaconda has mostly gone into maintenance mode, and is much slower with bug fixes than VSC in that regard, but this hasn't affected me by a lot since most of the core functionality is pretty stable.
I really recommend giving Anaconda+ST a try for your Python dev needs.
"Open image in a new tab" to the rescue! The extension I use (Dark Reader) didn't force dark mode for images, which means I can see the labels just fine in these cases.