// synchronized wrapper around its normal return value".
// Define this here to spare some nesting.
public Set entrySet() {
class SynchronizedMapEntry implements Map.Entry, Rollbackable {
protected transient Checkpoint $CHECKPOINT = new Checkpoint(this);
final Map.Entry e;
SynchronizedMapEntry(Object o) {
e = (Map.Entry)o;
}
/**
* Returns <code>true</code> if the object, o, implements <code>Map.Entry</code>
* with the same key and value as the underlying entry. A lock is
* obtained on the mutex before the comparison takes place.
* @param o The object to compare with this entry.
* @return <code>true</code> if o is equivalent to the underlying map entry.
*/
public boolean equals(Object o) {
synchronized (mutex) {
return e.equals(o);
}
}
/**
* Returns the key used in the underlying map entry. A lock is obtained
* on the mutex before the key is retrieved.
* @return The key of the underlying map entry.
*/
public Object getKey() {
synchronized (mutex) {
return e.getKey();
}
}
/**
* Returns the value used in the underlying map entry. A lock is obtained
* on the mutex before the value is retrieved.
* @return The value of the underlying map entry.
*/
public Object getValue() {
synchronized (mutex) {
return e.getValue();
}
}
/**
* Computes the hash code for the underlying map entry.
* This computation is described in the documentation for the
* <code>Map</code> interface. A lock is obtained on the mutex
* before the underlying map is accessed.
* @return The hash code of the underlying map entry.
* @see Map#hashCode()
*/
public int hashCode() {
synchronized (mutex) {
return e.hashCode();
}
}
/**
* Replaces the value in the underlying map entry with the specified
* object (optional operation). A lock is obtained on the mutex
* before the map is altered. The map entry, in turn, will alter
* the underlying map object. The operation is undefined if the
* <code>remove()</code> method of the iterator has been called
* beforehand.
* @param value the new value to store
* @return the old value
* @throws UnsupportedOperationException if the operation is not supported.
* @throws ClassCastException if the value is of the wrong type.
* @throws IllegalArgumentException if something about the value
* prevents it from existing in this map.
* @throws NullPointerException if the map forbids null values.
*/
public Object setValue(Object value) {
synchronized (mutex) {
return e.setValue(value);
}
}
/**
* Returns a textual representation of the underlying map entry.
* A lock is obtained on the mutex before the entry is accessed.
* @return The contents of the map entry in <code>String</code> form.
*/
public String toString() {
synchronized (mutex) {
return e.toString();
}
}
public void $COMMIT(long timestamp) {
FieldRecord.commit($RECORDS, timestamp, $RECORD$$CHECKPOINT.getTopTimestamp());
$RECORD$$CHECKPOINT.commit(timestamp);
}
public void $RESTORE(long timestamp, boolean trim) {
if (timestamp <= $RECORD$$CHECKPOINT.getTopTimestamp()) {
$CHECKPOINT = $RECORD$$CHECKPOINT.restore($CHECKPOINT, this, timestamp, trim);
FieldRecord.popState($RECORDS);
$RESTORE(timestamp, trim);
}
}
public final Checkpoint $GET$CHECKPOINT() {
return $CHECKPOINT;
}
public final Object $SET$CHECKPOINT(Checkpoint checkpoint) {
if ($CHECKPOINT != checkpoint) {
Checkpoint oldCheckpoint = $CHECKPOINT;
if (checkpoint != null) {
$RECORD$$CHECKPOINT.add($CHECKPOINT, checkpoint.getTimestamp());
FieldRecord.pushState($RECORDS);
}
$CHECKPOINT = checkpoint;
oldCheckpoint.setCheckpoint(checkpoint);
checkpoint.addObject(this);
}
return this;
}
protected transient CheckpointRecord $RECORD$$CHECKPOINT = new CheckpointRecord();
private transient FieldRecord[] $RECORDS = new FieldRecord[] {
};
}
// class SynchronizedMapEntry
// Now the actual code.
if (entries == null)
synchronized (mutex) {
$ASSIGN$entries(new SynchronizedSet(mutex, m.entrySet()) {
/**
* Returns an iterator over the set. The iterator has no specific order,
* unless further specified. A lock is obtained on the set's mutex
* before the iterator is created. The created iterator is also
* thread-safe.
* @return A synchronized set iterator.
*/
public Iterator iterator() {
synchronized (super.mutex) {
return new SynchronizedIterator(super.mutex, c.iterator()) {
/**
* Retrieves the next map entry from the iterator.
* A lock is obtained on the iterator's mutex before
* the entry is created. The new map entry is enclosed in
* a thread-safe wrapper.
* @return A synchronized map entry.
*/
public Object next() {
synchronized (super.mutex) {
return new SynchronizedMapEntry(super.next());
}
}
final class _PROXY_ implements Rollbackable {
public final void $COMMIT(long timestamp) {
$COMMIT_ANONYMOUS(timestamp);
}
public final void $RESTORE(long timestamp, boolean trim) {
$RESTORE_ANONYMOUS(timestamp, trim);
}
public final Checkpoint $GET$CHECKPOINT() {
return $GET$CHECKPOINT_ANONYMOUS();
}
public final Object $SET$CHECKPOINT(Checkpoint checkpoint) {
$SET$CHECKPOINT_ANONYMOUS(checkpoint);
return this;
}
}
public void $COMMIT_ANONYMOUS(long timestamp) {
FieldRecord.commit($RECORDS, timestamp, $RECORD$$CHECKPOINT.getTopTimestamp());
super.$COMMIT(timestamp);
}
public void $RESTORE_ANONYMOUS(long timestamp, boolean trim) {
super.$RESTORE(timestamp, trim);
}
public final Checkpoint $GET$CHECKPOINT_ANONYMOUS() {
return $CHECKPOINT;
}
public final Object $SET$CHECKPOINT_ANONYMOUS(Checkpoint checkpoint) {
if ($CHECKPOINT != checkpoint) {
Checkpoint oldCheckpoint = $CHECKPOINT;
if (checkpoint != null) {
$RECORD$$CHECKPOINT.add($CHECKPOINT, checkpoint.getTimestamp());
FieldRecord.pushState($RECORDS);
}
$CHECKPOINT = checkpoint;
oldCheckpoint.setCheckpoint(checkpoint);
checkpoint.addObject(new _PROXY_());
}
return this;
}
private transient FieldRecord[] $RECORDS = new FieldRecord[] {
};
{
$CHECKPOINT.addObject(new _PROXY_());
}
};
}
}
final class _PROXY_ implements Rollbackable {
public final void $COMMIT(long timestamp) {
$COMMIT_ANONYMOUS(timestamp);
}
public final void $RESTORE(long timestamp, boolean trim) {
$RESTORE_ANONYMOUS(timestamp, trim);
}
public final Checkpoint $GET$CHECKPOINT() {
return $GET$CHECKPOINT_ANONYMOUS();
}
public final Object $SET$CHECKPOINT(Checkpoint checkpoint) {
$SET$CHECKPOINT_ANONYMOUS(checkpoint);
return this;
}
}
public void $COMMIT_ANONYMOUS(long timestamp) {
FieldRecord.commit($RECORDS, timestamp, $RECORD$$CHECKPOINT.getTopTimestamp());
super.$COMMIT(timestamp);
}
public void $RESTORE_ANONYMOUS(long timestamp, boolean trim) {
super.$RESTORE(timestamp, trim);
}
public final Checkpoint $GET$CHECKPOINT_ANONYMOUS() {
return $CHECKPOINT;
}
public final Object $SET$CHECKPOINT_ANONYMOUS(Checkpoint checkpoint) {
if ($CHECKPOINT != checkpoint) {
Checkpoint oldCheckpoint = $CHECKPOINT;
if (checkpoint != null) {
$RECORD$$CHECKPOINT.add($CHECKPOINT, checkpoint.getTimestamp());
FieldRecord.pushState($RECORDS);
}
$CHECKPOINT = checkpoint;
oldCheckpoint.setCheckpoint(checkpoint);
checkpoint.addObject(new _PROXY_());
}
return this;
}