RSSAmplifier

Blog

Random thoughts on concurrency, databases and distributed systems

Core database engineer at QuestDB. Distributed systems gazer. Node.js contributor. Occasional tech blogger and speaker.

puzpuzpuz.devRSS feed ↗16 posts

Latest posts

Multithreaded Execution Model for Queries With ORDER BY and LIMIT Clauses

This small post continues the previous post dedicated to multithreaded query execution in databases with column-oriented storage format. This time we'll consider queries like the following: SELECT SearchPhrase FROM hits WHERE SearchPhrase IS NOT NULL...

An mmap-based hash table optimization

mmap is a controversial topic among the database community. The common belief is that it's no good for a database, but in my experience, it does a decent job for an analytical database, when you want to scan columns stored in a column-oriented format...

Seqlock-Based Atomic Memory Snapshots

Last time we discussed k-word CAS algorithm and came to the conclusion that seqlock-based atomic snapshots may be used as an alternative in situations when your writes are infrequent and single-writer limitation is acceptable, but you want the reader...

A Few Thoughts on K-Word CAS

A few months ago I went through Efficient Multi-word Compare and Swap paper, so here are a few thoughts on the algorithm. Long story short, I have mixed feelings about this k-word CAS algorithm. It focuses on nice properties of the CAS operation, suc...

The Secret Life of fsync

Several times I've heard opinions that many mass-market SSDs and HDDs don't provide sufficient durability guarantees and Linux can do nothing with that. Namely, after an fsync() call recently modified data can still sit in the drive's volatile write ...

Multithreaded Scatter-Gather Execution Model for Analytical Queries

Today we'll discuss an approach used in some analytical databases to speed up the execution of queries at the cost of additional HW resources, namely CPU cores and memory. The query execution model is usually referred to as "scatter-gather", yet it's...

BuzzwordBusters: What Does Lock-Free, Wait-Free Really Mean?

It seems to be a common belief that code which uses mutexes/locks/synchronized methods is "slow" and, as soon as you replace them with atomics, your code becomes fast and lock-free. Atomic operations don't make your code wait-free, lock-free, or even...

Concurrent Map in Go vs Java: Yet Another Meaningless Benchmark

Today we're comparing Java's j.u.c.ConcurrentHashMap and Go's xsync.MapOf in a totally non-scientific, unfair benchmark. While most of such language performance comparisons are generally useless and harmful, the purpose of this exercise is a comparis...

Thread-Local State in Go, Huh?

We all know that there is no such thing as thread-local state in Go. Yet, there is a trick that would help you to retain the thread identity at least on the hot path. This trick would be helpful if you're trying to implement a striped counter (wink-w...

So long, sync.Map

While the title is certainly a clickbait, I definitely don't see any strong reason to keep dealing with sync.Map if you're a Go generics user. Instead, you should consider xsync.MapOf: type point struct { x int y int } // create a MapOf for w...

Testing Concurrent Code for Fun and Profit

Everyone knows that multi-threaded code is not a piece of cake. There are lots of publications on how to write concurrent code properly and also lots of well-known algorithms and data structures to choose from. Yet, authors often ignore another impor...

Fast and Simple SPSC Queue

Single producer single consumer (SPSC) queues form the simplest type of concurrent queues. We have a single thread producing the items, as well as a single thread consuming them concurrently - what can be simpler than that? Nevertheless, such queues ...

Using Acquire/Release Semantics in Java Atomics for Fun and Profit

In case you've missed it, recent JDK versions include new memory semantics for atomic operations available in VarHandle and Atomic* classes. These new semantics are equivalent to C/C++'s std::memory_order. The only confusing naming convention is that...

Benchmarking Non-shared Locks in Java

Last time we discussed scalability of j.u.c.l.ReentrantReadWriteLock and some alternatives. Some of the alternatives used a simple CAS (compare-and-swap) based spinlock as the internal writer lock. So, I was curious whether such custom spinlock makes...

Scalable Readers-Writer Lock

Locks, or mutexes (mutual exclusions), are one of the most basic concurrency primitives. It's hard to find a developer who won't be able to explain a mutex, at least on the fundamental level. Yet, mutexes are more than that. They may be: OS-level (t...

My previous blog

My previous blog on Medium is located here. It's mostly focused on Node.js. You may also find my blog post in Gopher Advent 2021.