// Received an ACK @Override public void onAck() { // remove local cache but NOT in case it is already on disk // (ie memory can be reclaimed and we assume we have plenty of disk space) if (_dontCache && !_xval.isPersisted()) H2O.putIfMatch(_xkey, null, _xval); if (_xval != null) _xval.completeRemotePut(); }
@Override public void dinvoke(H2ONode sender) { assert _key.home() || _val == null; // Only PUT to home for keys, or remote invalidation from home Paxos.lockCloud(); // Initialize Value for having a single known replica (the sender) if (_val != null) _val.initReplicaHome(sender, _key); // Spin, until we update something. Value old = H2O.raw_get(_key); // Raw-get: do not lazy-manifest if overwriting while (H2O.putIfMatch(_key, _val, old) != old) old = H2O.raw_get(_key); // Repeat until we update something. // Invalidate remote caches. Block, so that all invalidates are done // before we return to the remote caller. if (_key.home() && old != null) old.lockAndInvalidate(sender, new Futures()).blockForPending(); // No return result _key = null; _val = null; tryComplete(); }
// Received an ACK; executes on the node asking&receiving the Value @Override public void onAck() { if (_val != null) { // Set transient fields after deserializing assert !_xkey.home() && _val._key == null; _val._key = _xkey; } // Now update the local store, caching the result. // We only started down the TGK path because we missed locally, so we only // expect to find a NULL in the local store. If somebody else installed // another value (e.g. a racing TGK, or racing local Put) this value must // be more recent than our NULL - but is UNORDERED relative to the Value // returned from the Home. We'll take the local Value to preserve ordering // and rely on invalidates from Home to force refreshes as needed. // Hence we can do a blind putIfMatch here over a null or empty Value // If it fails, what is there is also the TGK result. Value old = H2O.STORE.get(_xkey); if (old != null && !old.isEmpty()) old = null; Value res = H2O.putIfMatch(_xkey, _val, old); if (res != old) _val = res; TGKS.remove(_xkey); // Clear from dup cache }