judofyr
Joined 18 years ago
Joined 18 years ago
Sooo, the score is maybe mostly just how much they fit?
They don’t actually free the memory, but rather put it back into the memory pool with an incremented version counter. It can later be re-used as a new node, the version counter _not_ being reset.
In LeanStore’s use case they either way have a fixed amount of memory they’d like to use (since it’s a page buffer on top of disk data) so there’s no actual need to give the memory back to the OS.
If you’d like to actually free the memory back it’s a lot easier since you can now treat this more of an infrequent operation. The cost of that will be amortized very well.
EDIT: They also describe another very cool idea: If the memory is allocated with mmap you can deallocate it by using madvise DONT_NEED. This will cause the version counter to be “0” which you can interpret as “invalid”. You can then deallocate it at a later point when you’re absolutely sure no threads could access it. You’re basically doing a two-stage deallocation where the first stage releases the memory, but the page information is kept until the second stage.
Once you know this, you can start making educated guesses for the first weighing and quickly eliminate those which makes it impossible to continue. For instance: Splitting the marbles into two. This gives two possible outcomes: Left side is heaver or right side is heavier. For the first outcome it means that either the target marble is lighter and part of the left group (6 marbles) or heavier and part of the right group (6 marbles). That's 12 different possibilities (more than 9) and therefore we know that it's impossible to determine the marble with just two more weighings.
There's still guessing to be done, but at every part of the decision tree you can at the very least quickly avoid exploring paths which are guaranteed to not work.
I also realized that this can be expressed in terms of a two pairs of sibling:
> Mary and Ann are the same age difference as Jane and Claire. Mary is 24 years old. Mary is twice as old as Jane. Claire is as old as Ann. How old is Ann?
This highlights also why it's so confusing:
> Mary is 24 years old. She [Mary, today] is twice as old as Ann was [Ann, past] when Mary was [Mary, past] as old as Ann is [Ann, today] now. How old is Ann?
In one sentence we're comparing past and present ages.
Mary is 24 years old. When Mary was Ann’s current age, Ann was 12 years old (half Mary’s current age).
This makes it a bit easier to realize that Ann’s age has to be right in the middle of 12 and 24.
- while none of this is exaggerated
- it comes down to a real design choice
- the bloat, the amplified writes, the vacuum babysitting
- every charge traces to a decision, not a defect
- the verdict that spreads from community to community always stops one question early
- watch the damage happen yourself
Here's one way of how to write it in simpler language:
> These are not user mistakes and it's easy to reproduce these issues in a few lines of SQL on the latest version of Postgres. We're going to go through each of these problematic cases one by one to understand what's happening. Next, we're going to look at how other databases are solving it. Turns out there is no silver-bullet here: Postgres just makes a different set of trade-offs than other databases.
EDIT: And you can read for yourself how the LLM rates these two paragraphs compared to each other: https://chatgpt.com/share/6a6a3120-fec4-83eb-9c8b-dbb6294aa5...
attic
That way you can just create an attic directory in any project where you can keep random stuff that should never be committed. I’ve yet to find a repo which actually has such a directory checker in. // Precise matching:
assert_f64_eq!(a, 0.1, Steps(2))
// same as: assert!(a == 0.1.next_down().next_down())
// Number of digits (after period) that are matching:
assert_f64_eq!(a, 0.1, Digits(5))
// Relative error:
assert_f64_eq!(a, 0.1, Rel(0.5))> A store operation with this memory order performs the release operation: no reads or writes in the current thread can be reordered after this store. All writes in the current thread are visible in other threads that acquire the same atomic variable (see Release-Acquire ordering below) and writes that carry a dependency into the atomic variable become visible in other threads that consume the same atomic (see Release-Consume ordering below).
However, looking at the recent commits it doesn't quite look like the most solid foundation: https://github.com/shuaimu/rusty-cpp/commit/480491121ef9efec...
fn is_interior_mutability_type(type_name: &str) -> bool {
type_name.starts_with("rusty::Cell<") ||
type_name.starts_with("Cell<") ||
type_name.starts_with("rusty::RefCell<") ||
type_name.starts_with("RefCell<") ||
// Also check for std::atomic which has interior mutability
type_name.starts_with("std::atomic<") ||
type_name.starts_with("atomic<")
}
… which then 30 minutes later is being removed again because it turns out to be completely dead code: https://github.com/shuaimu/rusty-cpp/commit/84aae5eff72bb450...There's also quite a lot of dead code. All of these warnings are around unused variable, functions, structs, fields:
warning: `rusty-cpp` (bin "rusty-cpp-checker") generated 90 warnings (44 duplicates) struct slot {
uint32_t key;
uint32_t value;
}I would be unhappy with the carpenter, yes. But if the toolmaker was constantly over-promising (lying?), lobbying with governments, pushing their tools into the hands of carpenters, never taking responsibility, then I would also criticize the toolmaker. It’s also a toolmaker’s responsibility to be honest about what the tool should be used for.
I think it’s a bit too simplistic to say «AI is not the problem» with the current state of the industry.