judofyr
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.
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.
And yet, we’re not supposed to criticize the tool or its makers? Clearly there’s more problems in this world than «lazy carpenters»?
Saying «I know that correlation doesn’t imply causation», but then only demonstrating correlation isn’t really bringing this discourse any further.
def foo
p 1
yield
p 2
end
foo { break }
This only prints "1" because the break stops the execution of the invoked method (foo).This adds some complexity in the language, but it means that it’s far more expressive. In Ruby you can with nothing but Array#each write idiomatic code which reads very similar to other traditional languages with loops and statements.
Well, this all depends on the definition of «function properly». Convergence ensures that everyone observed the same state, not that it’s a useful state. For instance, The Imploding Hashmap is a very easy CRDT to implement. The rule is that when there’s concurrent changes to the same key, the final value becomes null. This gives Strong Eventual Consistency, but isn’t really a very useful data structure. All the data would just disappear!
So yes, CRDT is a massively useful property which we should strive for, but it’s not going to magically solve all the end-user problems.
Except for Zsh (~/.zshrc), SSH (~/.ssh/config), Vim (~/.vimrc), Curl (~/.curlrc), Git (~/.gitconfig). Apple could have chosen to patch these and move the configuration files into ~/Library if they really wanted.
There's many scientists who have published the "contrary". They were not ostracized from science or from society as a whole. These saw next to none negative impact to their position while they were alive. Other scientists have published rebuttals and later some of the originals articles have been retracted.
J. Philippe Rushton: 250 published articles, 6 books, the most famous university professor in Canada. Retractions of this work came 8 years after his death.
Arthur Jensen: Wrote a controversial paper in 1969. Ended up publishing 400 articles. Remained a professor for his full life.
Hans Eysenck: The most cited living psychologist in peer-reviewed scientific journal literature. It took more than 20 years before any of his papers were retracted.
There's a lot of published articles about the "contrary view" that you can read. You can also read the rebuttals by the current scientific consensus (cited above).
> The analogous claim would therefore be that “although height differences have a large hereditary component, it does not follow that disparities in height between families have a genetic basis.” This seems very clearly false to me.
But this is not an analogous claim since you're talking about disparities between families. The analogous claim would be: "although height differences have a large hereditary component, it does not follow that disparities in height between groups have a genetic basis".
A very simple example for height[1]: The Japanese grew 10 cm taller from mid-20th century to early 2000s. Originally people thought that the shortness of the Japanese was related to their genetics, but this rapid growth (which also correlates with their improved economy) suggests that the group difference between Japanese and other groups was not related to the genetic component of height variance.
[1]: Secular Changes in Relative Height of Children in Japan, South Korea and Taiwan: Is “Genetics” the Key Determinant? https://biomedgrid.com/pdf/AJBSR.MS.ID.000857.pdf
> Although IQ differences between individuals have been shown to have a large hereditary component, it does not follow that disparities in IQ between groups have a genetic basis[18][19][20][21]. The scientific consensus is that genetics does not explain average differences in IQ test performance between racial groups.[22][23][24][25][26][27].
Sequential consistency mostly become relevant when you have more than two threads interacting with both reads and writes. However, if you only have single-consumer (i.e. only one thread reading) or single-producer (i.e. only one thread writing) then the acquire-release semantics ends up becoming sequential since the single-consumer/producer implicitly enforces a sequential ordering. I can potentially see some multi-producer multi-consumer queues lock-free queues needing sequential atomics.
I think it's rare to see atomics with sequential consistency in practice since you typically either choose (1) a mutex to simplify the code at the expense of locking or (2) acquire-release (or weaker) to minimize the synchronization.
This volatile keyword appears to only consider that specific memory location whereas the Volatile class seem to implement acquire-release.
- While I'm working on something I can do `jj desc` and start writing the commit message. Every edit is automatically being added to this change.
- My work tree is dirty and I quickly want to switch to a clean slate. In Git: (1) either do `git stash` where I'm definitely is going to forget about it or (2) do `git commit -a -m wip && git switch -c some-random-branch-name`. In jj: `jj new @-`. That's it! If I run `jj log` then my previous change shows up. No need to come up with arbitrary names. It's so refreshing to move changes around.
- I'm working on a stack of changes and sometimes need to make edits to different parts. In Git (1): Each change is its own branch and I need to switch around and do a bunch of rebases to keep them in sync. In Git (2): I have one branch with multiple commits. I make changes towards the final state and then do `git rebase -i` to move them upwards to where they belong. Biggest downside: I'm not actually testing the changes at the point where they end up and I'm not guaranteed it makes sense. In jj: I do `jj new <CHANGE>` to make changes further up in the stack. Once I'm happy with it I do `jj squash` and every dependent change is automatically rebased on top.
- And finally: I can solve merge conflicts when I want to! If any rebasing leads to a merge conflict I don't have to deal with it right away.
«inline else» is also very powerful tool to easily abstract away code with no runtime cost.
The performance of high-contention code is a really tricky to reason about and depends on a lot of factors. Just replacing a mutex with a lock-free data structure will not magically speed up your code. Eliminating the contention completely is typically much better in general.
export OPENAPI_API_KEY=$(op read "op://api-prod/openai/api-key")
Every time you cd into the directory it will execute the command. Isn’t this even better than copying the secret into a local file?