protected ClientKeyBlock encode(
     ObjectContainer container, ClientContext context, boolean calledByCB) throws InsertException {
   if (persistent) {
     container.activate(sourceData, 1);
     container.activate(cb, 1);
   }
   ClientKeyBlock block;
   boolean shouldSend;
   synchronized (this) {
     if (finished) return null;
     if (sourceData == null) {
       Logger.error(this, "Source data is null on " + this + " but not finished!");
       return null;
     }
     block = innerEncode(context.random, container);
     shouldSend = (resultingURI == null);
     resultingURI = block.getClientKey().getURI();
   }
   if (logMINOR)
     Logger.minor(
         this,
         "Encoded "
             + resultingURI
             + " for "
             + this
             + " shouldSend="
             + shouldSend
             + " dontSendEncoded="
             + dontSendEncoded);
   if (shouldSend && !dontSendEncoded) cb.onEncode(block.getClientKey(), this, container, context);
   if (shouldSend && persistent) container.store(this);
   if (persistent && !calledByCB) container.deactivate(cb, 1);
   return block;
 }
 public void schedule(ObjectContainer container, ClientContext context) throws InsertException {
   synchronized (this) {
     if (finished) {
       if (logMINOR) Logger.minor(this, "Finished already: " + this);
       return;
     }
   }
   if (getCHKOnly) {
     boolean deactivateCB = false;
     if (persistent) {
       deactivateCB = !container.ext().isActive(cb);
       if (deactivateCB) container.activate(cb, 1);
       container.activate(parent, 1);
     }
     ClientKeyBlock block = encode(container, context, true);
     cb.onEncode(block.getClientKey(), this, container, context);
     parent.completedBlock(false, container, context);
     cb.onSuccess(this, container, context);
     finished = true;
     if (persistent) {
       container.store(this);
       if (deactivateCB) container.deactivate(cb, 1);
     }
   } else {
     getScheduler(context).registerInsert(this, persistent, true, container);
   }
 }
 /**
  * Convert a ClientKeyBlock to a Bucket. If an error occurs, report it via onFailure and return
  * null.
  */
 protected Bucket extract(
     ClientKeyBlock block, Object token, ObjectContainer container, ClientContext context) {
   Bucket data;
   try {
     data =
         block.decode(
             context.getBucketFactory(persistent),
             (int) (Math.min(ctx.maxOutputLength, Integer.MAX_VALUE)),
             false);
   } catch (KeyDecodeException e1) {
     if (Logger.shouldLog(Logger.MINOR, this)) Logger.minor(this, "Decode failure: " + e1, e1);
     onFailure(
         new FetchException(FetchException.BLOCK_DECODE_ERROR, e1.getMessage()),
         token,
         container,
         context);
     return null;
   } catch (TooBigException e) {
     onFailure(
         new FetchException(FetchException.TOO_BIG, e.getMessage()), token, container, context);
     return null;
   } catch (IOException e) {
     Logger.error(this, "Could not capture data - disk full?: " + e, e);
     onFailure(new FetchException(FetchException.BUCKET_ERROR, e), token, container, context);
     return null;
   }
   if (Logger.shouldLog(Logger.MINOR, this))
     Logger.minor(
         this, data == null ? "Could not decode: null" : ("Decoded " + data.size() + " bytes"));
   return data;
 }
    public boolean send(
        NodeClientCore core, RequestScheduler sched, final ClientContext context, ChosenBlock req) {
      // Ignore keyNum, key, since we're only sending one block.
      ClientKeyBlock b;
      ClientKey key = null;
      if (SingleBlockInserter.logMINOR)
        Logger.minor(this, "Starting request: " + SingleBlockInserter.this);
      BlockItem block = (BlockItem) req.token;
      try {
        try {
          b =
              innerEncode(
                  context.random,
                  block.uri,
                  block.copyBucket,
                  block.isMetadata,
                  block.compressionCodec,
                  block.sourceLength,
                  compressorDescriptor);
        } catch (CHKEncodeException e) {
          throw new LowLevelPutException(
              LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e);
        } catch (SSKEncodeException e) {
          throw new LowLevelPutException(
              LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e);
        } catch (MalformedURLException e) {
          throw new LowLevelPutException(
              LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e);
        } catch (InsertException e) {
          throw new LowLevelPutException(
              LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e);
        } catch (IOException e) {
          throw new LowLevelPutException(
              LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e);
        } catch (InvalidCompressionCodecException e) {
          throw new LowLevelPutException(
              LowLevelPutException.INTERNAL_ERROR, e.toString() + ":" + e.getMessage(), e);
        }
        if (b == null) {
          Logger.error(
              this,
              "Asked to send empty block on " + SingleBlockInserter.this,
              new Exception("error"));
          return false;
        }
        key = b.getClientKey();
        final ClientKey k = key;
        if (block.persistent) {
          context.jobRunner.queue(
              new DBJob() {

                public boolean run(ObjectContainer container, ClientContext context) {
                  if (!container.ext().isStored(SingleBlockInserter.this)) return false;
                  container.activate(SingleBlockInserter.this, 1);
                  onEncode(k, container, context);
                  container.deactivate(SingleBlockInserter.this, 1);
                  return false;
                }
              },
              NativeThread.NORM_PRIORITY + 1,
              false);
        } else {
          context.mainExecutor.execute(
              new Runnable() {

                public void run() {
                  onEncode(k, null, context);
                }
              },
              "Got URI");
        }
        if (req.localRequestOnly)
          try {
            core.node.store(b, false, req.canWriteClientCache, true, false);
          } catch (KeyCollisionException e) {
            throw new LowLevelPutException(LowLevelPutException.COLLISION);
          }
        else core.realPut(b, req.canWriteClientCache, req.forkOnCacheable);
      } catch (LowLevelPutException e) {
        if (e.code == LowLevelPutException.COLLISION) {
          // Collision
          try {
            ClientSSKBlock collided =
                (ClientSSKBlock)
                    core.node.fetch((ClientSSK) key, true, true, req.canWriteClientCache);
            byte[] data = collided.memoryDecode(true);
            byte[] inserting = BucketTools.toByteArray(block.copyBucket);
            if (collided.isMetadata() == block.isMetadata
                && collided.getCompressionCodec() == block.compressionCodec
                && Arrays.equals(data, inserting)) {
              if (SingleBlockInserter.logMINOR)
                Logger.minor(this, "Collided with identical data: " + SingleBlockInserter.this);
              req.onInsertSuccess(context);
              return true;
            }
          } catch (KeyVerifyException e1) {
            Logger.error(this, "Caught " + e1 + " when checking collision!", e1);
          } catch (KeyDecodeException e1) {
            Logger.error(this, "Caught " + e1 + " when checking collision!", e1);
          } catch (IOException e1) {
            Logger.error(this, "Caught " + e1 + " when checking collision!", e1);
          }
        }
        req.onFailure(e, context);
        if (SingleBlockInserter.logMINOR)
          Logger.minor(this, "Request failed: " + SingleBlockInserter.this + " for " + e);
        return true;
      } catch (DatabaseDisabledException e) {
        // Impossible, and nothing to do.
        Logger.error(this, "Running persistent insert but database is disabled!");
      } finally {
        block.copyBucket.free();
      }
      if (SingleBlockInserter.logMINOR)
        Logger.minor(this, "Request succeeded: " + SingleBlockInserter.this);
      req.onInsertSuccess(context);
      return true;
    }