/** * "pop" operation ends if destPage is found, if destPage is not found, the method call is a no-op * * @param destPage page as the destination for this pop operation * @param animated true to animate the transition */ public void popToPage( Page destPage, boolean animated, PageAnimator.AnimationDirection animationDirection) { if (mAnimating) { return; } if (destPage == null) { throw new IllegalArgumentException("cannot call popToPage() with null destPage."); } if (mPageStack.size() <= 0 || mPageStack.lastIndexOf(destPage) == -1 || mPageStack.peekLast() == destPage) { return; } Page oldPage = mPageStack.removeLast(); if (mEnableDebug) { Log.d(TAG, String.format(">>>> popPage, pagestack=%d, %s", mPageStack.size(), oldPage)); } while (mPageStack.size() > 1) { if (mPageStack.peekLast() == destPage) { break; } Page page = mPageStack.removeLast(); page.onHide(); mContainerView.removeView(page.getView()); page.onDetached(); page.onHidden(); } popPageInternal(oldPage, animated, animationDirection); }
/** * Reports true if the path in question violates the happens before relation of pickups and drop * offs. * * @param path * @param pairs * @return */ private boolean happensBeforeViolation( LinkedList<Vertex> path, ArrayList<ArrayList<Vertex>> pairs) { for (int i = 0; i < pairs.size(); i++) { Vertex pickup = pairs.get(i).get(0); Vertex dropoff = pairs.get(i).get(1); int pickupIndex = path.indexOf(pickup); int dropoffIndex = path.lastIndexOf(dropoff); if (dropoffIndex < pickupIndex) { return true; } } return false; }
public int lastIndexOf(Object o) { // Specified by: lastIndexOf in interface java.util.List return (linkedlist.lastIndexOf(o)); }
/** * Releases the read lock held by the provided transaction. If it is null then an attempt to * acquire the current transaction will be made. This is to make safe calling the method from the * context of an <code>afterCompletion()</code> hook where the tx is locally stored and not * necessarily available through the tm. If there are waiting transactions in the queue they will * be interrupted if they can acquire the lock. */ synchronized void releaseReadLock(Object tx) throws LockNotFoundException { TxLockElement tle = getLockElement(tx); if (tle.readCount == 0) { throw new LockNotFoundException("" + tx + " don't have readLock"); } totalReadCount--; tle.readCount--; if (tle.isFree()) { txLockElementMap.remove(tx); ragManager.lockReleased(this, tx); } if (waitingThreadList.size() > 0) { WaitElement we = waitingThreadList.getLast(); if (we.lockType == LockType.WRITE) { // this one is tricky... // if readCount > 0 we either have to find a waiting read lock // in the queue or a waiting write lock that has all read // locks, if none of these are found it means that there // is a (are) thread(s) that will release read lock(s) in the // near future... if (totalReadCount == we.element.readCount) { // found a write lock with all read locks waitingThreadList.removeLast(); if (!we.element.movedOn) { we.waitingThread.interrupt(); } } else { ListIterator<WaitElement> listItr = waitingThreadList.listIterator(waitingThreadList.lastIndexOf(we)); // hm am I doing the first all over again? // think I am if cursor is at lastIndex + 0.5 oh well... while (listItr.hasPrevious()) { we = listItr.previous(); if (we.lockType == LockType.WRITE && totalReadCount == we.element.readCount) { // found a write lock with all read locks listItr.remove(); if (!we.element.movedOn) { we.waitingThread.interrupt(); // ---- break; } } else if (we.lockType == LockType.READ) { // found a read lock, let it do the job... listItr.remove(); if (!we.element.movedOn) { we.waitingThread.interrupt(); } } } } } else { // some thread may have the write lock and released a read lock // if writeCount is down to zero we can interrupt the waiting // read lock if (totalWriteCount == 0) { waitingThreadList.removeLast(); if (!we.element.movedOn) { we.waitingThread.interrupt(); } } } } }