COWAL::replaceAll is the method that allows you to compose read operations
under the internal lock. For example, swap can be built with a stateful
UnaryOperator.
private static void swap(List l, int i, int j) {
l.replaceAll(new UnaryOperator() {
int cursor;
Object tmp;
//This is run while lock is held so size is frozen.
public Object apply(Object t) {
if (cursor == 0) {
if (i >= j)
throw new IllegalArgumentException();
tmp = l.get(i);
l.get(j); //Bounds check
}
Object r;
if (cursor == i) {
r = l.get(j);
} else if (cursor == j) {
r = tmp;
} else {
r = t;
}
++cursor;
return r;
}
});
}
This eliminates one extra internal array copy versus the Collections::swap for
COWAL. The method signature for my example swap doesn't make much sense if
COWAL is mutating (add/remove) since I'm supplying indexes as arguments.
Implementing a public swap method on COWAL would have the same problem.
Jason
________________________________________
From: Zelva Lia <[email protected]>
Sent: Wednesday, August 24, 2022 5:46 PM
To: Jason Mehrens
Cc: [email protected]
Subject: Re: CopyOnWriteArrayList Collection.shuffle
Well, yes, this is a solvable problem, albeit with additional copying, but
solvable, which cannot be said about other operations (for example, swap), I
lead to the fact that there are few specialized methods in COW that can work
inside synchronization and cannot be synchronized with by the COWArrayList
object itself, because it is synchronized with its private lock