/** Wait for the global readPoint to advance upto the specified transaction number. */
 public void waitForRead(WriteEntry e) {
   boolean interrupted = false;
   synchronized (readWaiters) {
     while (memstoreRead < e.getWriteNumber()) {
       try {
         readWaiters.wait(0);
       } catch (InterruptedException ie) {
         // We were interrupted... finish the loop -- i.e. cleanup --and then
         // on our way out, reset the interrupt flag.
         interrupted = true;
       }
     }
   }
   if (interrupted) Thread.currentThread().interrupt();
 }
  /**
   * Mark the {@link WriteEntry} as complete and advance the read point as much as possible.
   *
   * <p>How much is the read point advanced? Let S be the set of all write numbers that are
   * completed and where all previous write numbers are also completed. Then, the read point is
   * advanced to the supremum of S.
   *
   * @param e
   * @return true if e is visible to MVCC readers (that is, readpoint >= e.writeNumber)
   */
  boolean advanceMemstore(WriteEntry e) {
    synchronized (writeQueue) {
      e.markCompleted();

      long nextReadValue = -1;
      boolean ranOnce = false;
      while (!writeQueue.isEmpty()) {
        ranOnce = true;
        WriteEntry queueFirst = writeQueue.getFirst();

        if (nextReadValue > 0) {
          if (nextReadValue + 1 != queueFirst.getWriteNumber()) {
            throw new RuntimeException(
                "invariant in completeMemstoreInsert violated, prev: "
                    + nextReadValue
                    + " next: "
                    + queueFirst.getWriteNumber());
          }
        }

        if (queueFirst.isCompleted()) {
          nextReadValue = queueFirst.getWriteNumber();
          writeQueue.removeFirst();
        } else {
          break;
        }
      }

      if (!ranOnce) {
        throw new RuntimeException("never was a first");
      }

      if (nextReadValue > 0) {
        synchronized (readWaiters) {
          memstoreRead = nextReadValue;
          readWaiters.notifyAll();
        }
      }
      if (memstoreRead >= e.getWriteNumber()) {
        return true;
      }
      return false;
    }
  }