public synchronized StoredBlock get(Sha256Hash hash) throws BlockStoreException { ensureOpen(); // Check the memory cache first. StoredBlock fromMem = blockCache.get(hash); if (fromMem != null) { return fromMem; } if (notFoundCache.get(hash) == notFoundMarker) { return null; } try { Record fromDisk = getRecord(hash); StoredBlock block = null; if (fromDisk == null) { notFoundCache.put(hash, notFoundMarker); } else { block = fromDisk.toStoredBlock(params); blockCache.put(hash, block); } return block; } catch (IOException e) { throw new BlockStoreException(e); } catch (ProtocolException e) { throw new BlockStoreException(e); } }
private Record getRecord(Sha256Hash hash) throws IOException, ProtocolException { long startPos = channel.position(); // Use our own file pointer within the tight loop as updating channel positions is really // expensive. long pos = startPos; Record record = new Record(); int numMoves = 0; long startTime = new Date().getTime(); do { if (!record.read(channel, pos, buf)) throw new IOException("Failed to read buffer"); if (record.getHeader(params).getHash().equals(hash)) { // Found it. Update file position for next time. channel.position(pos); long endTime = new Date().getTime(); if (endTime - startTime > 100) { log.info( "Spent {} seconds doing {} backwards seeks", (endTime - startTime) / 1000.0, numMoves); } return record; } // Did not find it. if (pos == 1 + 32) { // At the start so wrap around to the end. pos = channel.size() - Record.SIZE; } else { // Move backwards. pos = pos - Record.SIZE; checkState(pos >= 1 + 32, pos); } numMoves++; } while (pos != startPos); // Was never stored. channel.position(pos); long endTime = new Date().getTime(); if (endTime - startTime > 1000) { log.info( "Spent {} seconds doing {} backwards seeks", (endTime - startTime) / 1000.0, numMoves); } return null; }
public synchronized void put(StoredBlock block) throws BlockStoreException { ensureOpen(); try { Sha256Hash hash = block.getHeader().getHash(); // Append to the end of the file. Record.write(channel, block); blockCache.put(hash, block); } catch (IOException e) { throw new BlockStoreException(e); } }