{
Versioned<VListNode<E>> firstNode = new Versioned<VListNode<E>>(VListNode.<E> valueOf(firstNodeMap.getValue()),
firstNodeMap.getVersion());
if(!firstNode.getValue().isStable()) {
throw new ObsoleteVersionException("cannot add when list node is not stable");
}
// set stable flag to false
Map<String, Object> tmpMap = new HashMap<String, Object>(firstNodeMap.getValue());
tmpMap.put(VListNode.STABLE, false);
storeClient.put(newKey.mapValue(),
new Versioned<Map<String, Object>>(tmpMap, firstNodeMap.getVersion()));
_rollback.put(0, firstNodeMap.getValue());
int newId;
int nextId = firstNode.getValue().getNextId();
newId = (nextId == VStack.NULL_ID) ? 1 : nextId + 1;
if(newId == Integer.MAX_VALUE)
throw new ArrayIndexOutOfBoundsException(newId + " out of bounds");
Versioned<VListNode<E>> nextNode = null;
VListKey<K> nextKey = new VListKey<K>(_key, nextId);
if(nextId != VStack.NULL_ID) {
Versioned<Map<String, Object>> nextNodeMap = storeClient.get(nextKey.mapValue());
if(nextNodeMap == null)
throw new ObsoleteVersionException("possible concurrent modification");
nextNode = new Versioned<VListNode<E>>(VListNode.<E> valueOf(nextNodeMap.getValue()),
nextNodeMap.getVersion());
if(!nextNode.getValue().isStable()) {
throw new ObsoleteVersionException("cannot add when list node is not stable");
}
// set stable flag to false
tmpMap = new HashMap<String, Object>(nextNode.getValue().mapValue());
tmpMap.put(VListNode.STABLE, false);
storeClient.put(nextKey.mapValue(),
new Versioned<Map<String, Object>>(tmpMap, nextNode.getVersion()));
_rollback.put(nextId, nextNode.getValue().mapValue());
}
// insert new node
Map<String, Object> newNode = (new VListNode<E>(_value, 0, VStack.NULL_ID, newId, true)).mapValue();
// don't need to specify versioned because node is already "locked"
storeClient.put(newKey.mapValue(), newNode);
// move first node to next index
VListKey<K> firstKey = new VListKey<K>(_key, newId);
firstNode = new Versioned<VListNode<E>>(new VListNode<E>(firstNode.getValue()
.getValue(),
newId,
0,
firstNode.getValue()
.getNextId(),
true));
// don't need to specify versioned because node is already "locked"
storeClient.put(firstKey.mapValue(), firstNode.getValue().mapValue());
// redefine previous pointer on next node
if(nextNode != null) {
if(!storeClient.applyUpdate(new UpdateNextNode<K, E>(nextNode, nextKey, newId)))
throw new ObsoleteVersionException("unable to update node");
}
}
}