.NET
Concurrent max value
For a feature in RavenDB, I need to figure out the maximum number of outputs per document an index has. Now, indexing runs in multiple threads at the same time, so we ended up with the following code:
var actualIndexOutput = maxActualIndexOutput;
if (actualIndexOutput > numberOfAlreadyProducedOutputs)
{
// okay, now let verify that this is indeed the case, in thread safe manner,
// this way, most of the time we don't need volatile reads, and other sync operations
// in the code ensure we don't have too stale a view on the data (beside, stale view have
// to mean a smaller number, which we then verify).
actualIndexOutput = Thread.VolatileRead(ref maxActualIndexOutput);
while (actualIndexOutput > numberOfAlreadyProducedOutputs)
{
// if it changed, we don't care, it is just another max, and another thread probably
// set it for us, so we only retry if this is still smaller
actualIndexOutput = Interlocked.CompareExchange(
ref maxActualIndexOutput,
numberOfAlreadyProducedOutputs,
actualIndexOutput);
}
}
The basic idea is that this code path is hit a lot, once per document indexed per index. And it also needs to be thread safe, so we first do an unsafe operation, then a thread safe operations.
The idea is that we’ll quickly arrive at the actual max number of index inputs, but we don’t have to pay the price of volatile reads or thread synchronization.
Reference: | Concurrent max value from our NCG partner Oren Eini at the Ayende @ Rahien blog. |