/** * Adds group reservation to this partition. * * @param r Reservation. * @return {@code false} If such reservation already added. */ public boolean addReservation(GridDhtPartitionsReservation r) { assert state.getReference() != EVICTED : "we can reserve only active partitions"; assert state.getStamp() != 0 : "partition must be already reserved before adding group reservation"; return reservations.addIfAbsent(r); }
/** * @param updateSeq Update sequence. * @return {@code True} if entry has been transitioned to state EVICTED. */ boolean tryEvict(boolean updateSeq) { if (state.getReference() != RENTING || state.getStamp() != 0 || groupReserved()) return false; // Attempt to evict partition entries from cache. clearAll(); if (map.isEmpty() && state.compareAndSet(RENTING, EVICTED, 0, 0)) { if (log.isDebugEnabled()) log.debug("Evicted partition: " + this); if (!GridQueryProcessor.isEnabled(cctx.config())) clearSwap(); if (cctx.isDrEnabled()) cctx.dr().partitionEvicted(id); cctx.dataStructures().onPartitionEvicted(id); rent.onDone(); ((GridDhtPreloader) cctx.preloader()).onPartitionEvicted(this, updateSeq); clearDeferredDeletes(); return true; } return false; }
/** attemptStamp succeeds in single thread */ public void testAttemptStamp() { int[] mark = new int[1]; AtomicStampedReference ai = new AtomicStampedReference(one, 0); assertEquals(0, ai.getStamp()); assertTrue(ai.attemptStamp(one, 1)); assertEquals(1, ai.getStamp()); assertSame(one, ai.get(mark)); assertEquals(1, mark[0]); }
/** * Reserves a partition so it won't be cleared. * * @return {@code True} if reserved. */ @Override public boolean reserve() { while (true) { int reservations = state.getStamp(); GridDhtPartitionState s = state.getReference(); if (s == EVICTED) return false; if (state.compareAndSet(s, s, reservations, reservations + 1)) return true; } }
/** * @param updateSeq Update sequence. * @return Future for evict attempt. */ IgniteInternalFuture<Boolean> tryEvictAsync(boolean updateSeq) { if (map.isEmpty() && !GridQueryProcessor.isEnabled(cctx.config()) && state.compareAndSet(RENTING, EVICTED, 0, 0)) { if (log.isDebugEnabled()) log.debug("Evicted partition: " + this); clearSwap(); if (cctx.isDrEnabled()) cctx.dr().partitionEvicted(id); cctx.dataStructures().onPartitionEvicted(id); rent.onDone(); ((GridDhtPreloader) cctx.preloader()).onPartitionEvicted(this, updateSeq); clearDeferredDeletes(); return new GridFinishedFuture<>(true); } return cctx.closures() .callLocalSafe( new GPC<Boolean>() { @Override public Boolean call() { return tryEvict(true); } }, /*system pool*/ true); }
/** compareAndSet in one thread enables another waiting for reference value to succeed */ public void testCompareAndSetInMultipleThreads() throws Exception { final AtomicStampedReference ai = new AtomicStampedReference(one, 0); Thread t = new Thread( new CheckedRunnable() { public void realRun() { while (!ai.compareAndSet(two, three, 0, 0)) Thread.yield(); } }); t.start(); assertTrue(ai.compareAndSet(one, two, 0, 0)); t.join(LONG_DELAY_MS); assertFalse(t.isAlive()); assertSame(three, ai.getReference()); assertEquals(0, ai.getStamp()); }
/** Releases previously reserved partition. */ @Override public void release() { while (true) { int reservations = state.getStamp(); if (reservations == 0) return; GridDhtPartitionState s = state.getReference(); assert s != EVICTED; // Decrement reservations. if (state.compareAndSet(s, s, reservations, --reservations)) { tryEvict(true); break; } } }
public void revertRestartRequired(Object stamp) { // If 'state' still has the state we last set in restartRequired(), change to RUNNING Integer theirStamp = Integer.class.cast(stamp); synchronized (service) { if (state.compareAndSet( State.RESTART_REQUIRED, State.RUNNING, theirStamp, this.stamp.incrementAndGet())) { service.stateChanged(State.RUNNING); } } }
public Object setRestartRequired() { AtomicStampedReference<State> stateRef = state; int newStamp = stamp.incrementAndGet(); int[] receiver = new int[1]; // Keep trying until stateRef is RESTART_REQUIRED with our stamp for (; ; ) { State was = stateRef.get(receiver); if (was == State.STARTING || was == State.STOPPING) { break; } synchronized (service) { if (stateRef.compareAndSet(was, State.RESTART_REQUIRED, receiver[0], newStamp)) { service.stateChanged(State.RESTART_REQUIRED); break; } } } return Integer.valueOf(newStamp); };
/** * @param updateSeq Update sequence. * @return Future to signal that this node is no longer an owner or backup. */ IgniteInternalFuture<?> rent(boolean updateSeq) { while (true) { int reservations = state.getStamp(); GridDhtPartitionState s = state.getReference(); if (s == RENTING || s == EVICTED) return rent; if (state.compareAndSet(s, RENTING, reservations, reservations)) { if (log.isDebugEnabled()) log.debug("Moved partition to RENTING state: " + this); // Evict asynchronously, as the 'rent' method may be called // from within write locks on local partition. tryEvictAsync(updateSeq); break; } } return rent; }
/** @return {@code True} if transitioned to OWNING state. */ boolean own() { while (true) { int reservations = state.getStamp(); GridDhtPartitionState s = state.getReference(); if (s == RENTING || s == EVICTED) return false; if (s == OWNING) return true; assert s == MOVING; if (state.compareAndSet(MOVING, OWNING, reservations, reservations)) { if (log.isDebugEnabled()) log.debug("Owned partition: " + this); // No need to keep history any more. evictHist = null; return true; } } }
/** constructor initializes to given reference and stamp */ public void testConstructor() { AtomicStampedReference ai = new AtomicStampedReference(one, 0); assertSame(one, ai.getReference()); assertEquals(0, ai.getStamp()); AtomicStampedReference a2 = new AtomicStampedReference(null, 1); assertNull(a2.getReference()); assertEquals(1, a2.getStamp()); }
/** * compareAndSet succeeds in changing values if equal to expected reference and stamp else fails */ public void testCompareAndSet() { int[] mark = new int[1]; AtomicStampedReference ai = new AtomicStampedReference(one, 0); assertSame(one, ai.get(mark)); assertEquals(0, ai.getStamp()); assertEquals(0, mark[0]); assertTrue(ai.compareAndSet(one, two, 0, 0)); assertSame(two, ai.get(mark)); assertEquals(0, mark[0]); assertTrue(ai.compareAndSet(two, m3, 0, 1)); assertSame(m3, ai.get(mark)); assertEquals(1, mark[0]); assertFalse(ai.compareAndSet(two, m3, 1, 1)); assertSame(m3, ai.get(mark)); assertEquals(1, mark[0]); }
public boolean attemptModifyASR() { boolean modified = false; IntendedModification currentlyOngoingMod = ongoingMod.getReference(); int stamp = ongoingMod.getStamp(); if (currentlyOngoingMod == null) { // copy data structure state - for use // in intended modification // prepare intended modification IntendedModification newMod = new IntendedModification(); // compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp) {} boolean modSubmitted = ongoingMod.compareAndSet(null, newMod, stamp, stamp + 1); if (modSubmitted) { // complete modification via a series of compare-and-swap operations. // note: other threads may assist in completing the compare-and-swap // operations, so some CAS may fail modified = true; } } else { // attempt to complete ongoing modification, so the data structure is fired up // to allow access from this thread. modified = false; } return modified; }
/** repeated weakCompareAndSet succeeds in changing values when equal to expected */ public void testWeakCompareAndSet() { int[] mark = new int[1]; AtomicStampedReference ai = new AtomicStampedReference(one, 0); assertSame(one, ai.get(mark)); assertEquals(0, ai.getStamp()); assertEquals(0, mark[0]); do {} while (!ai.weakCompareAndSet(one, two, 0, 0)); assertSame(two, ai.get(mark)); assertEquals(0, mark[0]); do {} while (!ai.weakCompareAndSet(two, m3, 0, 1)); assertSame(m3, ai.get(mark)); assertEquals(1, mark[0]); }
public State getState() { return state.getReference(); }
public void setStarting() { synchronized (service) { state.set(State.STARTING, stamp.incrementAndGet()); service.stateChanged(State.STARTING); } }
/** get returns the last values of reference and stamp set */ public void testGetSet() { int[] mark = new int[1]; AtomicStampedReference ai = new AtomicStampedReference(one, 0); assertSame(one, ai.getReference()); assertEquals(0, ai.getStamp()); assertSame(one, ai.get(mark)); assertEquals(0, mark[0]); ai.set(two, 0); assertSame(two, ai.getReference()); assertEquals(0, ai.getStamp()); assertSame(two, ai.get(mark)); assertEquals(0, mark[0]); ai.set(one, 1); assertSame(one, ai.getReference()); assertEquals(1, ai.getStamp()); assertSame(one, ai.get(mark)); assertEquals(1, mark[0]); }
public void setRunning() { synchronized (service) { state.set(State.RUNNING, stamp.incrementAndGet()); service.stateChanged(State.RUNNING); } }
/** @return Reservations. */ public int reservations() { return state.getStamp(); }
/** @return Partition state. */ public GridDhtPartitionState state() { return state.getReference(); }