synchronized boolean[] copyDownloadedBlocks() { return blockChooser.copyDownloadedBlocks(); }
synchronized public long countSendableKeys(long now, int maxRetries) { if(finished || tryDecode) return 0; return blockChooser.countFetchable(); }
synchronized long getCooldownTime(int blockNumber) { if(finished || succeeded || failed || failedRetries) return 0; return blockChooser.getCooldownTime(blockNumber); }
return saved; // Don't double remove from bloom filter! if(blockChooser.hasSucceeded(blockNumber)) { if(logMINOR) Logger.minor(this, "Already have block "+blockNumber); blockNumber = blockChooser.getBlockNumber(keys, key); if(logMINOR) Logger.minor(this, "Trying block "+blockNumber); continue; if(blockChooser.successCount() >= blocksForDecode()) { if(logMINOR) Logger.minor(this, "Already decoding"); assert(slotNumber != -1); blocksFetched[slotNumber] = blockNumber; blockChooser.onSuccess(blockNumber); RAFLock lock = parent.lockRAFOpen(); try { } catch (IOException e) { blocksFetched[slotNumber] = -1; blockChooser.onUnSuccess(blockNumber); Logger.error(this, "Unable to write downloaded block to disk: "+e, e); throw e; callback = crossSegmentsByBlock[blockNumber]; nextBlockNumber = (short) blockChooser.getBlockNumber(keys, key); metadataDirty = true;
blocksFetched[i] = s; if(s >= 0) { if(!blockChooser.hasSucceeded(s)) { blockChooser.onSuccess(s); } else { throw new StorageFormatException("Duplicated block number in blocksFetched in "+this); blockChooser.readRetries(dis); failedBlocks = blockChooser.countFailedBlocks(); if(failedBlocks >= checkBlocks) { failedRetries = true;
/** Pick a key to fetch. Must not update any persistent field. (Cooldowns etc are fine) */ public int chooseRandomKey() { int chosen; synchronized(this) { if(finished) return -1; if(failedRetries) return -1; if(tryDecode) { if(logMINOR) Logger.minor(this, "Segment decoding so not choosing a key on "+this); return -1; } if(corruptMetadata) return -1; // Will be fetchable after we've found out what blocks we actually have. chosen = blockChooser.chooseKey(); if(chosen != -1) { if(logMINOR) Logger.minor(this, "Chosen key "+chosen+"/"+totalBlocks()+" for "+this+" (retries "+blockChooser.getRetries(chosen)+"/"+blockChooser.maxRetries+")"); } else { if(logMINOR) Logger.minor(this, "No keys chosen for "+this); } } if(chosen == -1) { long cooldownTime = blockChooser.overallCooldownTime(); if(cooldownTime > System.currentTimeMillis()) parent.increaseCooldown(this, cooldownTime); return -1; } else { return chosen; } }
if(logMINOR) Logger.minor(this, "Non-fatal failure on block "+blockNumber+" for "+this+" for "+parent); synchronized(this) { long cooldown = blockChooser.overallCooldownTime(); if(blockChooser.onNonFatalFailure(blockNumber)) { if(logMINOR) Logger.minor(this, "Giving up on block "+blockNumber+" on "+this); givenUp = true; if(logMINOR) Logger.minor(this, "Block "+blockNumber+" on "+this+" : "+blockChooser.getRetries(blockNumber)+"/"+blockChooser.maxRetries); if(blockChooser.overallCooldownTime() < cooldown) wake = true; write = true;
synchronized(this) { if(succeeded || failed || finished) return false; blockNumber = blockChooser.getBlockNumber(keys, key); if(blockNumber == -1) { if(logMINOR) Logger.minor(this, "Block not found "+key); return false; if(blockChooser.hasSucceeded(blockNumber)) return false; // Even if this is inaccurate, it will be corrected on a FEC attempt. if(tryDecode)
public synchronized byte[] checkAndGetBlockData(int blockNum) throws IOException { if(!blockChooser.hasSucceeded(blockNum)) return null; ClientCHK key = getKey(blockNum); if(key == null) return null; for(int i=0;i<blocksFetched.length;i++) { if(blocksFetched[i] == blockNum) { byte[] buf = readBlock(i); try { ClientCHKBlock block = ClientCHKBlock.encodeSplitfileBlock(buf, key.getCryptoKey(), key.getCryptoAlgorithm()); if(!(block.getClientKey().equals(key))) { Logger.error(this, "Block "+blockNum+" in blocksFound["+i+"] is not valid!"); blockChooser.onUnSuccess(blockNum); succeeded = false; finished = false; } else { return buf; } } catch (CHKEncodeException e) { // Should not be possible. Logger.error(this, "Impossible: "+e); return null; } } } Logger.error(this, "Block "+blockNum+" in blocksFound but not in blocksFetched on "+this); return null; }
public synchronized boolean hasBlock(int blockNo) { return blockChooser.hasSucceeded(blockNo); }
boolean ignoreLastBlock = (segNo == parent.segments.length-1 && parent.lastBlockMightNotBePadded()); this.blockChooser = new SplitFileFetcherSegmentBlockChooser(total, parent.random, parent.maxRetries, parent.cooldownTries, parent.cooldownLength, this, keysFetching, ignoreLastBlock ? dataBlocks - 1 : -1);
private void queueHeal(byte[][] dataBlocks, byte[][] checkBlocks, boolean[] dataBlocksPresent, boolean[] checkBlocksPresent) throws IOException { for(int i=0;i<dataBlocks.length;i++) { if(dataBlocksPresent[i]) continue; if(blockChooser.getRetries(i) == 0) continue; queueHeal(i, dataBlocks[i]); } for(int i=0;i<checkBlocks.length;i++) { if(checkBlocksPresent[i]) continue; if(blockChooser.getRetries(i+dataBlocks.length) == 0) continue; queueHeal(i+dataBlocks.length, checkBlocks[i]); } }
public boolean definitelyWantKey(NodeCHK key) { synchronized(this) { if(succeeded || failed || finished) return false; } SplitFileSegmentKeys keys; try { keys = getSegmentKeys(); } catch (IOException e) { parent.failOnDiskError(e); return false; } synchronized(this) { // Synched because of blocksFound return blockChooser.getBlockNumber(keys, key) >= 0; } }
public synchronized void getUnfetchedKeys(List<Key> keys) throws IOException { if(finished || tryDecode) return; SplitFileSegmentKeys keyList = getSegmentKeys(); for(int i=0;i<totalBlocks();i++) { if(!blockChooser.hasSucceeded(i)) keys.add(keyList.getNodeKey(i, null, false)); } }
boolean ignoreLastBlock = (segNo == parent.segments.length-1 && parent.lastBlockMightNotBePadded()); blockChooser = new SplitFileFetcherSegmentBlockChooser(total, parent.random, parent.maxRetries, parent.cooldownTries, parent.cooldownLength, this, keysFetching, ignoreLastBlock ? dataBlocks - 1 : -1);