public void registerInsert(
      final SendableRequest req, boolean persistent, boolean regmeOnly, ObjectContainer container) {
    if (!isInsertScheduler)
      throw new IllegalArgumentException("Adding a SendableInsert to a request scheduler!!");
    if (persistent) {
      if (regmeOnly) {
        long bootID = 0;
        boolean queueFull = jobRunner.getQueueSize(NativeThread.NORM_PRIORITY) >= QUEUE_THRESHOLD;
        if (!queueFull) bootID = this.node.bootID;
        final RegisterMe regme =
            new RegisterMe(req, req.getPriorityClass(container), schedCore, null, bootID);
        container.store(regme);
        if (logMINOR) Logger.minor(this, "Added insert RegisterMe: " + regme);
        if (!queueFull) {
          try {
            jobRunner.queue(
                new DBJob() {

                  @Override
                  public boolean run(ObjectContainer container, ClientContext context) {
                    container.delete(regme);
                    if (req.isCancelled(container)) {
                      if (logMINOR) Logger.minor(this, "Request already cancelled");
                      return false;
                    }
                    if (container.ext().isActive(req))
                      Logger.error(this, "ALREADY ACTIVE: " + req + " in delayed insert register");
                    container.activate(req, 1);
                    registerInsert(req, true, false, container);
                    container.deactivate(req, 1);
                    return true;
                  }

                  @Override
                  public String toString() {
                    return "registerInsert";
                  }
                },
                NativeThread.NORM_PRIORITY,
                false);
          } catch (DatabaseDisabledException e) {
            // Impossible, we are already on the database thread.
          }
        } else {
          schedCore.rerunRegisterMeRunner(jobRunner);
        }
        container.deactivate(req, 1);
        return;
      }
      schedCore.innerRegister(req, random, container, clientContext, null);
      starter.wakeUp();
    } else {
      schedTransient.innerRegister(req, random, null, clientContext, null);
      starter.wakeUp();
    }
  }
 public void removeFromAllRequestsByClientRequest(
     ClientRequester clientRequest,
     SendableRequest get,
     boolean dontComplain,
     ObjectContainer container) {
   if (get.persistent())
     schedCore.removeFromAllRequestsByClientRequest(get, clientRequest, dontComplain, container);
   else
     schedTransient.removeFromAllRequestsByClientRequest(get, clientRequest, dontComplain, null);
 }
 /**
  * @param request
  * @param container
  * @return True if the queue is now full/over-full.
  */
 boolean addToStarterQueue(SendableRequest request, ObjectContainer container) {
   if (logMINOR) Logger.minor(this, "Adding to starter queue: " + request);
   container.activate(request, 1);
   PersistentChosenRequest chosen;
   try {
     chosen =
         new PersistentChosenRequest(
             request,
             request.getPriorityClass(container),
             container,
             ClientRequestScheduler.this,
             clientContext);
   } catch (NoValidBlocksException e) {
     return false;
   }
   if (logMINOR) Logger.minor(this, "Created PCR: " + chosen);
   container.deactivate(request, 1);
   boolean dumpNew = false;
   synchronized (starterQueue) {
     for (PersistentChosenRequest req : starterQueue) {
       if (req.request == request) {
         Logger.error(
             this, "Already on starter queue: " + req + " for " + request, new Exception("debug"));
         dumpNew = true;
         break;
       }
     }
     if (!dumpNew) {
       starterQueue.add(chosen);
       int length = starterQueueLength();
       length += chosen.sizeNotStarted();
       runningPersistentRequests.add(request);
       if (logMINOR)
         Logger.minor(
             this,
             "Added to running persistent requests, size now "
                 + runningPersistentRequests.size()
                 + " : "
                 + request);
       return length > MAX_STARTER_QUEUE_SIZE;
     }
   }
   if (dumpNew) chosen.onDumped(schedCore, container, false);
   return false;
 }
 @Override
 public void removeRunningRequest(SendableRequest request, ObjectContainer container) {
   synchronized (starterQueue) {
     for (int i = 0; i < runningPersistentRequests.size(); i++) {
       if (runningPersistentRequests.get(i) == request) {
         runningPersistentRequests.remove(i);
         i--;
         if (logMINOR)
           Logger.minor(
               this,
               "Removed running request "
                   + request
                   + " size now "
                   + runningPersistentRequests.size());
       }
     }
   }
   // We *DO* need to call clearCooldown here because it only becomes runnable for persistent
   // requests after it has been removed from starterQueue.
   boolean active = container.ext().isActive(request);
   if (!active) container.activate(request, 1);
   request.clearCooldown(container, clientContext, false);
   if (!active) container.deactivate(request, 1);
 }
 /**
  * Compare a recently registered SendableRequest to what is already on the starter queue. If it is
  * better, kick out stuff from the queue until we are just over the limit.
  *
  * @param req
  * @param container
  */
 public void maybeAddToStarterQueue(
     SendableRequest req, ObjectContainer container, SendableRequest[] mightBeActive) {
   short prio = req.getPriorityClass(container);
   if (logMINOR) Logger.minor(this, "Maybe adding to starter queue: prio=" + prio);
   synchronized (starterQueue) {
     boolean betterThanSome = false;
     int size = 0;
     PersistentChosenRequest prev = null;
     for (PersistentChosenRequest old : starterQueue) {
       if (old.request == req) {
         // Wait for a reselect. Otherwise we can starve other
         // requests. Note that this happens with persistent SBI's:
         // they are added at the new retry count before being
         // removed at the old retry count.
         if (logMINOR) Logger.minor(this, "Already on starter queue: " + old + " for " + req);
         return;
       }
       if (prev == old)
         Logger.error(this, "ON STARTER QUEUE TWICE: " + prev + " for " + prev.request);
       if (prev != null && prev.request == old.request)
         Logger.error(
             this,
             "REQUEST ON STARTER QUEUE TWICE: "
                 + prev
                 + " for "
                 + prev.request
                 + " vs "
                 + old
                 + " for "
                 + old.request);
       boolean ignoreActive = false;
       if (mightBeActive != null) {
         for (SendableRequest tmp : mightBeActive) if (tmp == old.request) ignoreActive = true;
       }
       if (!ignoreActive) {
         if (container.ext().isActive(old.request))
           Logger.warning(
               this,
               "REQUEST ALREADY ACTIVATED: "
                   + old.request
                   + " for "
                   + old
                   + " while checking request queue in maybeAddToStarterQueue for "
                   + req);
         else if (logDEBUG)
           Logger.debug(
               this,
               "Not already activated for "
                   + old
                   + " in while checking request queue in maybeAddToStarterQueue for "
                   + req);
       } else if (logMINOR)
         Logger.minor(
             this,
             "Ignoring active because just registered: "
                 + old.request
                 + " in maybeAddToStarterQueue for "
                 + req);
       size += old.sizeNotStarted();
       if (old.prio > prio) betterThanSome = true;
       if (old.request == req) return;
       prev = old;
     }
     if (size >= MAX_STARTER_QUEUE_SIZE && !betterThanSome) {
       if (logMINOR)
         Logger.minor(
             this,
             "Not adding to starter queue: over limit and req not better than any queued requests");
       return;
     }
   }
   addToStarterQueue(req, container);
   trimStarterQueue(container);
 }