org.apache.cassandra.utils.concurrent.IntrusiveStack Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cassandra-all Show documentation
Show all versions of cassandra-all Show documentation
The Apache Cassandra Project develops a highly scalable second-generation distributed database, bringing together Dynamo's fully distributed design and Bigtable's ColumnFamily-based data model.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.utils.concurrent;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import net.nicoulaj.compilecommand.annotations.Inline;
import org.apache.cassandra.utils.LongAccumulator;
/**
* An efficient stack/list that is expected to be ordinarily either empty or close to, and for which
* we need concurrent insertions and do not need to support removal - i.e. the list is semi immutable.
*
* This is an intrusive stack, and for simplicity we treat all
*
* @param
*/
public class IntrusiveStack> implements Iterable
{
static class Itr> implements Iterator
{
private T next;
Itr(T next)
{
this.next = next;
}
@Override
public boolean hasNext()
{
return next != null;
}
@Override
public T next()
{
T result = next;
next = result.next;
return result;
}
}
T next;
@Inline
protected static > T push(AtomicReferenceFieldUpdater super O, T> headUpdater, O owner, T prepend)
{
return push(headUpdater, owner, prepend, (prev, next) -> {
next.next = prev;
return next;
});
}
protected static > T push(AtomicReferenceFieldUpdater headUpdater, O owner, T prepend, BiFunction combine)
{
while (true)
{
T head = headUpdater.get(owner);
if (headUpdater.compareAndSet(owner, head, combine.apply(head, prepend)))
return head;
}
}
protected interface Setter
{
public boolean compareAndSet(O owner, T expect, T update);
}
@Inline
protected static > T push(Function getter, Setter setter, O owner, T prepend)
{
return push(getter, setter, owner, prepend, (prev, next) -> {
next.next = prev;
return next;
});
}
protected static > T push(Function getter, Setter setter, O owner, T prepend, BiFunction combine)
{
while (true)
{
T head = getter.apply(owner);
if (setter.compareAndSet(owner, head, combine.apply(head, prepend)))
return head;
}
}
protected static > void pushExclusive(AtomicReferenceFieldUpdater headUpdater, O owner, T prepend, BiFunction combine)
{
T head = headUpdater.get(owner);
headUpdater.lazySet(owner, combine.apply(head, prepend));
}
protected static , O> void pushExclusive(AtomicReferenceFieldUpdater headUpdater, O owner, T prepend)
{
prepend.next = headUpdater.get(owner);
headUpdater.lazySet(owner, prepend);
}
protected static > T pushExclusive(T head, T prepend)
{
prepend.next = head;
return prepend;
}
protected static , O> Iterable iterable(AtomicReferenceFieldUpdater headUpdater, O owner)
{
return iterable(headUpdater.get(owner));
}
protected static > Iterable iterable(T list)
{
return list == null ? () -> iterator(null) : list;
}
protected static > Iterator iterator(T list)
{
return new Itr<>(list);
}
protected static int size(IntrusiveStack> list)
{
int size = 0;
while (list != null)
{
++size;
list = list.next;
}
return size;
}
protected static > long accumulate(T list, LongAccumulator accumulator, long initialValue)
{
long value = initialValue;
while (list != null)
{
value = accumulator.apply(list, initialValue);
list = list.next;
}
return value;
}
// requires exclusive ownership (incl. with readers)
protected T reverse()
{
return reverse((T) this);
}
// requires exclusive ownership (incl. with readers)
protected static > T reverse(T list)
{
T prev = null;
T cur = list;
while (cur != null)
{
T next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
}
return prev;
}
@Override
public void forEach(Consumer super T> forEach)
{
forEach((T)this, forEach);
}
protected static > void forEach(T list, Consumer super T> forEach)
{
while (list != null)
{
forEach.accept(list);
list = list.next;
}
}
@Override
public Iterator iterator()
{
return new Itr<>((T) this);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy