Пример #1
0
 /**
  * Try to set or remove the value. When updating only unchanged entries, then the value is only
  * changed if it was not changed after opening the map.
  *
  * @param key the key
  * @param value the new value (null to remove the value)
  * @param onlyIfUnchanged only set the value if it was not changed (by this or another
  *     transaction) since the map was opened
  * @return true if the value was set
  */
 public boolean trySet(K key, V value, boolean onlyIfUnchanged) {
   Object[] current = map.get(key);
   if (onlyIfUnchanged) {
     Object[] old = getArray(key, readLogId);
     if (!map.areValuesEqual(old, current)) {
       long tx = (Long) current[0];
       if (tx == transaction.transactionId) {
         if (value == null) {
           // ignore removing an entry
           // if it was added or changed
           // in the same statement
           return true;
         } else if (current[2] == null) {
           // add an entry that was removed
           // in the same statement
         } else {
           return false;
         }
       } else {
         return false;
       }
     }
   }
   int opType;
   if (current == null || current[2] == null) {
     if (value == null) {
       // remove a removed value
       opType = Transaction.OP_SET;
     } else {
       opType = Transaction.OP_ADD;
     }
   } else {
     if (value == null) {
       opType = Transaction.OP_REMOVE;
     } else {
       opType = Transaction.OP_SET;
     }
   }
   Object[] newValue = {transaction.transactionId, transaction.logId, value};
   if (current == null) {
     // a new value
     Object[] old = map.putIfAbsent(key, newValue);
     if (old == null) {
       transaction.log(opType, mapId, key, current);
       return true;
     }
     return false;
   }
   long tx = (Long) current[0];
   if (tx == transaction.transactionId) {
     // added or updated by this transaction
     if (map.replace(key, current, newValue)) {
       transaction.log(opType, mapId, key, current);
       return true;
     }
     // strange, somebody overwrite the value
     // even thought the change was not committed
     return false;
   }
   // added or updated by another transaction
   boolean open = transaction.store.openTransactions.containsKey(tx);
   if (!open) {
     // the transaction is committed:
     // overwrite the value
     if (map.replace(key, current, newValue)) {
       transaction.log(opType, mapId, key, current);
       return true;
     }
     // somebody else was faster
     return false;
   }
   // the transaction is not yet committed
   return false;
 }