synchronized int innerChooseBlock() { if(cancelled) return -1; return blockChooser.chooseKey(); }
public int countSendableKeys() { return blockChooser.countFetchable(); }
/** Has the segment completed all inserts? * Should not change once we reach this state, but might be possible in case of disk errors * causing losing keys etc. */ public synchronized boolean hasSucceeded() { if(cancelled) return false; return blockChooser.hasSucceededAll(); }
try { readKey(blockNo); blockChooser.onRNF(blockNo); parent.clearCooldown(); return; if(blockChooser.pushRNFs(blockNo)) { parent.failTooManyRetriesInBlock(); return; if(blockChooser.onNonFatalFailure(blockNo)) { parent.failTooManyRetriesInBlock(); } else {
/** Handle an RNF if the n-consecutive-RNFs-count-as-success hack is enabled. * Must only be called if consecutiveRNFsCountAsSuccess > 0 */ public void onRNF(int blockNo) { synchronized(this) { assert(consecutiveRNFsCountAsSuccess > 0); if(++consecutiveRNFs[blockNo] < consecutiveRNFsCountAsSuccess) return; } onSuccess(blockNo); }
public SplitFileInserterSegmentStorage(SplitFileInserterStorage parent, int segNo, boolean persistent, int dataBlocks, int checkBlocks, int crossCheckBlocks, int keyLength, byte splitfileCryptoAlgorithm, byte[] splitfileCryptoKey, Random random, int maxRetries, int consecutiveRNFsCountAsSuccess, KeysFetchingLocally keysFetching) { this.parent = parent; this.segNo = segNo; this.dataBlockCount = dataBlocks; this.checkBlockCount = checkBlocks; this.crossCheckBlockCount = crossCheckBlocks; totalBlockCount = dataBlockCount + crossCheckBlockCount + checkBlockCount; this.keyLength = keyLength; crossSegmentBlockSegments = new SplitFileInserterCrossSegmentStorage[crossCheckBlocks]; crossSegmentBlockNumbers = new int[crossCheckBlocks]; blocksHaveKeys = new boolean[totalBlockCount]; this.splitfileCryptoAlgorithm = splitfileCryptoAlgorithm; this.splitfileCryptoKey = splitfileCryptoKey; crossDataBlocksAllocated = new boolean[dataBlocks + crossCheckBlocks]; blockChooser = new SplitFileInserterSegmentBlockChooser(this, totalBlockCount, random, maxRetries, keysFetching, consecutiveRNFsCountAsSuccess); try { CountedOutputStream cos = new CountedOutputStream(new NullOutputStream()); DataOutputStream dos = new DataOutputStream(cos); innerStoreStatus(dos); dos.close(); statusLength = (int) cos.written() + parent.checker.checksumLength(); } catch (IOException e) { throw new Error(e); // Impossible } }
/** Count the previous RNFs towards the retry limit, when the following error wasn't an RNF. */ public synchronized boolean pushRNFs(int blockNo) { int ret = consecutiveRNFs[blockNo]; consecutiveRNFs[blockNo] = 0; for(int i=0;i<ret;i++) if(onNonFatalFailure(blockNo)) return true; return false; }
public void readStatus() throws IOException, ChecksumFailedException, StorageFormatException { byte[] data = new byte[statusLength-parent.checker.checksumLength()]; parent.preadChecksummed(parent.getOffsetSegmentStatus(segNo), data, 0, data.length); DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data)); if(dis.readInt() != segNo) throw new StorageFormatException("Bad segment number"); encoded = dis.readBoolean(); blockChooser.read(dis); }
public ClientCHKBlock encodeBlock(int blockNo) throws IOException { if(parent.isFinishing()) { throw new IOException("Already finishing reading block "+blockNo+" for "+this+" for "+parent); } synchronized(this) { if(this.blockChooser.hasSucceeded(blockNo)) { Logger.error(this, "Already inserted block "+blockNo+" for "+this+" for "+parent); throw new IOException("Already inserted block "+blockNo+" for "+this+" for "+parent); } } byte[] buf = readBlock(blockNo); return encodeBlock(buf); }
/** Called when a block insert succeeds */ public void onInsertedBlock(int blockNo, ClientCHK key) { try { if(parent.hasFinished()) return; this.setKey(blockNo, key); if(blockChooser.onSuccess(blockNo)) parent.callback.onInsertedBlock(); lazyWriteMetadata(); } catch (IOException e) { if(parent.hasFinished()) return; // Race condition possible as this is a callback parent.failOnDiskError(e); } }
this.splitfileCryptoKey = splitfileCryptoKey; crossDataBlocksAllocated = new boolean[dataBlockCount + crossCheckBlockCount]; blockChooser = new SplitFileInserterSegmentBlockChooser(this, totalBlockCount, random, maxRetries, keysFetching, consecutiveRNFsCountAsSuccess); try {
public synchronized boolean hasCompletedOrFailed() { if(encoded) return true; // No more encoding jobs will run. if(encoding) return false; // Waiting for job to finish. if(cancelled) return true; if(blockChooser.hasSucceededAll()) return true; return false; }