mirror of
https://github.com/corda/corda.git
synced 2025-06-13 04:38:19 +00:00
implement ConcurrentHashMap and AtomicReferenceArray
This is the simplest possible ConcurrentHashMap I could come up with that works and is actually concurrent in the way one would expect. It's pretty unconventional, being based on a persistent red-black tree, and not particularly memory-efficient or cache-friendly. I think this is a good place to start, though, and it should perform reasonably well for most workloads. Patches for a more efficient implementation are welcome! I also implemented AtomicReferenceArray, since I was using it in my first, naive attempt to implement ConcurrentHashMap. I had to do a bit of refactoring, including moving some non-standard stuff from java.util.Collections to avian.Data so I could make it available to code outside the java.util package, which is why I had to modify several unrelated files.
This commit is contained in:
@ -32,9 +32,9 @@ public class AtomicReference<T> implements java.io.Serializable {
|
||||
public T get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public void set(T newValue) {
|
||||
this.value = newValue;
|
||||
value = newValue;
|
||||
}
|
||||
|
||||
public void lazySet(T newValue) {
|
||||
|
@ -0,0 +1,69 @@
|
||||
/* Copyright (c) 2008-2014, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.util.concurrent.atomic;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
public class AtomicReferenceArray<T> {
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private static final long arrayOffset = unsafe.arrayBaseOffset(Object.class);
|
||||
private static final long arrayScale = unsafe.arrayIndexScale(Object.class);
|
||||
|
||||
private final Object[] array;
|
||||
|
||||
public AtomicReferenceArray(int length) {
|
||||
array = new Object[length];
|
||||
}
|
||||
|
||||
public T get(int index) {
|
||||
return (T) unsafe.getObjectVolatile
|
||||
(array, arrayOffset + (index * arrayScale));
|
||||
}
|
||||
|
||||
public void set(int index, T newValue) {
|
||||
unsafe.putObjectVolatile
|
||||
(array, arrayOffset + (index * arrayScale), newValue);
|
||||
}
|
||||
|
||||
public void lazySet(int index, T newValue) {
|
||||
unsafe.putOrderedObject
|
||||
(array, arrayOffset + (index * arrayScale), newValue);
|
||||
}
|
||||
|
||||
public boolean compareAndSet(int index, T expect, T update) {
|
||||
return unsafe.compareAndSwapObject
|
||||
(array, arrayOffset + (index * arrayScale), expect, update);
|
||||
}
|
||||
|
||||
public boolean weakCompareAndSet(int index, T expect, T update) {
|
||||
return compareAndSet(index, expect, update);
|
||||
}
|
||||
|
||||
public final T getAndSet(int index, T newValue) {
|
||||
while (true) {
|
||||
T current = get(index);
|
||||
if (compareAndSet(index, current, newValue)) {
|
||||
return current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return array.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Arrays.toString(array);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user