Compare and Swap (CAS) implementation in EhCache

1.2k views Asked by At

I am trying to find an equivalent of MemCache's CASMutator.cas in EhCache. Essentially, I am swapping out EhCache for MemCache and need to implement an interface that calls for setting a value via CAS. Does anyone have any insight into this? Also, given that I'm not purporting to be an expert in any of this, if anyone has any high level overview of how CAS actually works / what it is doing, that would be appreciated as well.

1

There are 1 answers

0
Adam On BEST ANSWER

The compare and swap method equivalent in EhCache is the replace(Element old, Element element) method found in net.sf.ehcache.Cache. This method compares the "old" Element against the Element that is currently in the cache and, if it matches, replaces the Element in the cache with "element." The following method provides a simple usage example that assumes "aCache" is some Cache object to which the method has access and that "aCache" is used to cache objects of type Long.

// Replace the cached value associated with key with newValue and
// return the original value
public Long replace(String key, Long newValue, long maxTries)
    boolean success = false;
    Long originalValue;
    Element originalElement;
    Element newElement = new Element(key, newValue);

    for (int ii = 0; !success && ii < maxTries; ++ii) {
       // Get a copy of the original List           
       originalValue = (Long) aCache.get(key).getValue();

       // Make a duplicate of the Element that exists for "key"
       originalElement = new Element(key, originalValue);

       // if the value for inKey has not changed since setting originalValue,
       // replace the value for "key" with "newValue"
       if (aCache.replace(originalElement, newElement)) {
          success = true;
       }
    }

    if (!success) {
       originalValue = null;  
    }

    return originalValue;
}

Note that this only works if the key already exists in the cache. If it doesn't, then the call to aCache.replace returns false and does not put newElement into the cache. If you dig far enough into the internals of EhCache (the replace method of the Segment class in the net.sf.ehcache.store.compound package), you'll find that the replace is actually implemented by aquiring a write lock. That said, it could be presumed that aquiring a write lock is no different than using the replace method. As such, you could theoretically replace this whole function by calling aCache.aquireWriteLockOnKey, performing the needed actions, and then releasing the write lock.

An overview of Compare-and-Swap can be found on Wikipedia at: http://en.wikipedia.org/wiki/Compare-and-swap.