public String getLine(int lineNo) throws Exception { if (lineNo <= 0 || lineNo > mNumLines) { return null; } String line = null; Jedis jedis = pool_.getResource(); try { String lineNoStr = Integer.toString(lineNo); line = jedis.hget(lineNoStr, LINE_KEY); if (line == null) { RecordId lineId = getRecordId(lineNo); byte[] buffer = new byte[BLOCK_SIZE]; synchronized (mDataFile) { mDataFile.seek(lineId.pageNo() * BLOCK_SIZE); mDataFile.read(buffer); } ByteBuffer bb = ByteBuffer.wrap(buffer); int numRecords = bb.getInt(BLOCK_SIZE - INT_SIZE); int indexPos = BLOCK_SIZE - 3 * INT_SIZE; int curLineNo = lineNo - lineId.slotNo() + 1; String[] recordKeys = {PAGE_NO_KEY, SLOT_NO_KEY}; for (int i = 1; i < numRecords; i++, curLineNo++) { int offset = bb.getInt(indexPos); int len = bb.getInt(indexPos + INT_SIZE); ByteBuffer linebb = ByteBuffer.wrap(buffer, offset, len); byte[] lineBuf = new byte[linebb.remaining()]; linebb.get(lineBuf); String lineStr = new String(lineBuf); if (i == lineId.slotNo()) { line = lineStr; } // Store in cache lineNoStr = Integer.toString(curLineNo); jedis.hdel(lineNoStr, recordKeys); jedis.hset(lineNoStr, LINE_KEY, lineStr); indexPos -= 2 * INT_SIZE; } } if (line == null) { throw new Exception("LineServer: Could not find line on page"); } } catch (IOException ioe) { System.err.println("LineServer: IOException on line retrieval"); throw ioe; } finally { pool_.returnResource(jedis); } return line; }
/** * Assuming the file has an id3v2 tag, returns true if the tag can be overwritten. We cannot * overwrite id3v2 tags not supported * * @param raf * @return * @throws IOException */ private boolean canOverwrite(RandomAccessFile raf) throws IOException { raf.seek(3); // Version du tag ID3v2.xx.xx String versionHigh = raf.read() + ""; if (!(versionHigh.equals("4") || versionHigh.equals("3") || versionHigh.equals("2"))) return false; // only version 2.3.xx // raf.read(); // int flag = raf.read() & 128; // if (flag == 128) // return false; //unsynchronised tags not supported return true; }
private RecordId getRecordId(int lineNo) throws IOException { RecordId id = null; Jedis jedis = pool_.getResource(); try { int pageNo, slotNo; String lineNoStr = Integer.toString(lineNo); String pageNoStr = jedis.hget(lineNoStr, PAGE_NO_KEY); String slotNoStr = jedis.hget(lineNoStr, SLOT_NO_KEY); if (pageNoStr != null && slotNoStr != null) { id = new RecordId(Integer.parseInt(pageNoStr), Integer.parseInt(slotNoStr)); } else { // Was not cached // Read directory page containing line in question byte[] buffer = new byte[BLOCK_SIZE]; int absIndex = (lineNo - 1) * 2 * INT_SIZE; int relativeIndex = absIndex % BLOCK_SIZE; int bytesRead = 0; synchronized (mDirectoryFile) { mDirectoryFile.seek(absIndex - relativeIndex); bytesRead = mDirectoryFile.read(buffer); } ByteBuffer bb = ByteBuffer.wrap(buffer); // Cache all entries in the page int curLineNo = lineNo - relativeIndex / (2 * INT_SIZE); for (int i = 0; i < bytesRead / (2 * INT_SIZE); i++, curLineNo++) { pageNo = bb.getInt(); slotNo = bb.getInt(); if (curLineNo == lineNo) { id = new RecordId(pageNo, slotNo); } lineNoStr = Integer.toString(curLineNo); jedis.hset(lineNoStr, PAGE_NO_KEY, Integer.toString(pageNo)); jedis.hset(lineNoStr, SLOT_NO_KEY, Integer.toString(slotNo)); } } if (id == null) { throw new IOException("LineServer: Could not find record id in directory"); } } finally { pool_.returnResource(jedis); } return id; }
/** * Read block from file. * * @param file - File to read. * @param off - Marker position in file to start read from if {@code -1} read last blockSz bytes. * @param blockSz - Maximum number of chars to read. * @param lastModified - File last modification time. * @return Read file block. * @throws IOException In case of error. */ public static VisorFileBlock readBlock(File file, long off, int blockSz, long lastModified) throws IOException { RandomAccessFile raf = null; try { long fSz = file.length(); long fLastModified = file.lastModified(); long pos = off >= 0 ? off : Math.max(fSz - blockSz, 0); // Try read more that file length. if (fLastModified == lastModified && fSz != 0 && pos >= fSz) throw new IOException( "Trying to read file block with wrong offset: " + pos + " while file size: " + fSz); if (fSz == 0) return new VisorFileBlock(file.getPath(), pos, fLastModified, 0, false, EMPTY_FILE_BUF); else { int toRead = Math.min(blockSz, (int) (fSz - pos)); byte[] buf = new byte[toRead]; raf = new RandomAccessFile(file, "r"); raf.seek(pos); int cntRead = raf.read(buf, 0, toRead); if (cntRead != toRead) throw new IOException( "Count of requested and actually read bytes does not match [cntRead=" + cntRead + ", toRead=" + toRead + ']'); boolean zipped = buf.length > 512; return new VisorFileBlock( file.getPath(), pos, fSz, fLastModified, zipped, zipped ? zipBytes(buf) : buf); } } finally { U.close(raf, null); } }