示例#1
0
  public void close() {
    if (shuttingDown.getAndSet(true)) {
      return;
    }

    mutex.lock();
    try {
      while (backgroundCompaction != null) {
        backgroundCondition.awaitUninterruptibly();
      }
    } finally {
      mutex.unlock();
    }

    compactionExecutor.shutdown();
    try {
      compactionExecutor.awaitTermination(1, TimeUnit.DAYS);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
    }
    try {
      versions.destroy();
    } catch (IOException ignored) {
    }
    try {
      log.close();
    } catch (IOException ignored) {
    }
    tableCache.close();
    dbLock.release();
  }
示例#2
0
    void startIdleState() {
      lock.lock();
      try {
        final Thread currentThread = Thread.currentThread();
        final Thread currentIdleThread = threadsRequestingIdle.peekFirst();
        if (currentIdleThread == currentThread) {
          assert idleStateCount > 0;
          ++idleStateCount;
          assert idleStateCount > 0;
          return;
        }

        threadsRequestingIdle.add(currentThread);

        while ((activitiyCount > 0) || (threadsRequestingIdle.getFirst() != currentThread))
          condition.awaitUninterruptibly();

        assert idleStateCount == 0;
        assert activitiyCount == 0;
        assert threadsRequestingIdle.getFirst() == currentThread;
        idleStateCount = 1;

      } finally {
        lock.unlock();
      }
    }
示例#3
0
 void startRequest(boolean isFileScopeRequest) {
   lock.lock();
   try {
     while (!canStartRequest(isFileScopeRequest)) condition.awaitUninterruptibly();
     ++activitiyCount;
   } finally {
     lock.unlock();
   }
 }
 private void awaitForCloseUninterruptibly() {
   _mutex.lock();
   try {
     while (!isClosed()) {
       _connectionClosed.awaitUninterruptibly();
     }
   } finally {
     _mutex.unlock();
   }
 }
 /** Acquire one permit from the semaphore in a manner that cannot be interrupted. */
 public void acquireUninterruptibly() {
   // TODO - you fill in here.
   lock.lock();
   try {
     while (availablePermits() == 0) permitAvailable.awaitUninterruptibly();
     numAvailablePermits--;
   } finally {
     lock.unlock();
   }
 }
 /** Acquire one permit from the semaphore in a manner that cannot be interrupted. */
 public void acquireUninterruptibly() {
   // TODO - you fill in here.
   reentrantLock.lock();
   try {
     while (permits == 0) {
       condition.awaitUninterruptibly();
     }
     permits--;
   } finally {
     reentrantLock.unlock();
   }
 }
示例#7
0
 void endAllowingFileScopeRequests() {
   lock.lock();
   try {
     final Thread currentThread = Thread.currentThread();
     final Thread currentIdleThread = threadsRequestingIdle.peekFirst();
     assert currentThread == currentIdleThread;
     assert allowFileScopeRequests;
     while (activitiyCount > 0) condition.awaitUninterruptibly();
     allowFileScopeRequests = false;
   } finally {
     lock.unlock();
   }
 }
示例#8
0
  public void compactRange(int level, Slice start, Slice end) {
    Preconditions.checkArgument(level >= 0, "level is negative");
    Preconditions.checkArgument(
        level + 1 < NUM_LEVELS, "level is greater than or equal to %s", NUM_LEVELS);
    Preconditions.checkNotNull(start, "start is null");
    Preconditions.checkNotNull(end, "end is null");

    mutex.lock();
    try {
      while (this.manualCompaction != null) {
        backgroundCondition.awaitUninterruptibly();
      }
      ManualCompaction manualCompaction = new ManualCompaction(level, start, end);
      this.manualCompaction = manualCompaction;

      maybeScheduleCompaction();

      while (this.manualCompaction == manualCompaction) {
        backgroundCondition.awaitUninterruptibly();
      }
    } finally {
      mutex.unlock();
    }
  }
示例#9
0
  public void flushMemTable() {
    mutex.lock();
    try {
      // force compaction
      makeRoomForWrite(true);

      // todo bg_error code
      while (immutableMemTable != null) {
        backgroundCondition.awaitUninterruptibly();
      }

    } finally {
      mutex.unlock();
    }
  }
示例#10
0
  private void makeRoomForWrite(boolean force) {
    Preconditions.checkState(mutex.isHeldByCurrentThread());

    boolean allowDelay = !force;

    while (true) {
      // todo background processing system need work
      //            if (!bg_error_.ok()) {
      //              // Yield previous error
      //              s = bg_error_;
      //              break;
      //            } else
      if (allowDelay && versions.numberOfFilesInLevel(0) > L0_SLOWDOWN_WRITES_TRIGGER) {
        // We are getting close to hitting a hard limit on the number of
        // L0 files.  Rather than delaying a single write by several
        // seconds when we hit the hard limit, start delaying each
        // individual write by 1ms to reduce latency variance.  Also,
        // this delay hands over some CPU to the compaction thread in
        // case it is sharing the same core as the writer.
        try {
          mutex.unlock();
          Thread.sleep(1);
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
          throw new RuntimeException(e);
        } finally {
          mutex.lock();
        }

        // Do not delay a single write more than once
        allowDelay = false;
      } else if (!force && memTable.approximateMemoryUsage() <= options.writeBufferSize()) {
        // There is room in current memtable
        break;
      } else if (immutableMemTable != null) {
        // We have filled up the current memtable, but the previous
        // one is still being compacted, so we wait.
        backgroundCondition.awaitUninterruptibly();
      } else if (versions.numberOfFilesInLevel(0) >= L0_STOP_WRITES_TRIGGER) {
        // There are too many level-0 files.
        //                Log(options_.info_log, "waiting...\n");
        backgroundCondition.awaitUninterruptibly();
      } else {
        // Attempt to switch to a new memtable and trigger compaction of old
        Preconditions.checkState(versions.getPrevLogNumber() == 0);

        // close the existing log
        try {
          log.close();
        } catch (IOException e) {
          throw new RuntimeException("Unable to close log file " + log.getFile(), e);
        }

        // open a new log
        long logNumber = versions.getNextFileNumber();
        try {
          this.log =
              Logs.createLogWriter(
                  new File(databaseDir, Filename.logFileName(logNumber)), logNumber);
        } catch (IOException e) {
          throw new RuntimeException(
              "Unable to open new log file "
                  + new File(databaseDir, Filename.logFileName(logNumber)).getAbsoluteFile(),
              e);
        }

        // create a new mem table
        immutableMemTable = memTable;
        memTable = new MemTable(internalKeyComparator);

        // Do not force another compaction there is space available
        force = false;

        maybeScheduleCompaction();
      }
    }
  }
示例#11
0
  public Object down(Event evt) {
    switch (evt.getType()) {
      case Event.LOCK:
        LockInfo info = (LockInfo) evt.getArg();
        ClientLock lock = getLock(info.getName());
        if (!info.isTrylock()) {
          if (info.isLockInterruptibly()) {
            try {
              lock.lockInterruptibly();
            } catch (InterruptedException e) {
              Thread.currentThread()
                  .interrupt(); // has to be checked by caller who has to rethrow ...
            }
          } else lock.lock();
        } else {
          if (info.isUseTimeout()) {
            try {
              return lock.tryLock(info.getTimeout(), info.getTimeUnit());
            } catch (InterruptedException e) {
              Thread.currentThread().interrupt();
            }
          } else {
            return lock.tryLock();
          }
        }
        return null;

      case Event.UNLOCK:
        info = (LockInfo) evt.getArg();
        lock = getLock(info.getName(), false);
        if (lock != null) lock.unlock();
        return null;

      case Event.UNLOCK_ALL:
        unlockAll();
        return null;
      case Event.LOCK_AWAIT:
        info = (LockInfo) evt.getArg();
        lock = getLock(info.getName(), false);
        if (lock == null || !lock.acquired) {
          throw new IllegalMonitorStateException();
        }
        Condition condition = lock.newCondition();
        if (info.isUseTimeout()) {
          try {
            return condition.awaitNanos(info.getTimeUnit().toNanos(info.getTimeout()));
          } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
          }
        } else if (info.isLockInterruptibly()) {
          try {
            condition.await();
          } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
          }
        } else {
          condition.awaitUninterruptibly();
        }
        break;
      case Event.LOCK_SIGNAL:
        AwaitInfo awaitInfo = (AwaitInfo) evt.getArg();
        lock = getLock(awaitInfo.getName(), false);
        if (lock == null || !lock.acquired) {
          throw new IllegalMonitorStateException();
        }
        sendSignalConditionRequest(awaitInfo.getName(), awaitInfo.isAll());
        break;
      case Event.SET_LOCAL_ADDRESS:
        local_addr = (Address) evt.getArg();
        break;

      case Event.VIEW_CHANGE:
        handleView((View) evt.getArg());
        break;
    }
    return down_prot.down(evt);
  }