/** * Skip length bytes The same as readMultiPageData() without returning a result * * @param length number of bytes to skip * @param page current page * @param curPageOff in (current) and out (new) parameter at index 0 * @param nextPage in (current) and out (new) parameter at index 0 * @return current page */ public int skipMultiPageBytes(int length, int page, int[] curPageOff, int[] nextPage) throws IOException { int pageCounter = curPageOff[0]; int curNextPage = nextPage[0]; int curPage = page; int dct = 0; while (dct < length) { int len = PAGESIZE - pageCounter; if (len <= 0) { if (curNextPage <= 0) throw new IOException("not enough pages to skip"); BlockFile.pageSeek(this.file, curNextPage); int magic = this.file.readInt(); if (magic != MAGIC_CONT) throw new IOException( "Bad SkipSpan continuation magic number 0x" + Integer.toHexString(magic) + " on page " + curNextPage); curPage = curNextPage; curNextPage = this.file.readUnsignedInt(); pageCounter = BSkipSpan.CONT_HEADER_LEN; len = PAGESIZE - pageCounter; } int res = Math.min(len, length - dct); this.file.skipBytes(res); pageCounter += res; dct += res; } nextPage[0] = curNextPage; curPageOff[0] = pageCounter; return curPage; }
/** * Read bytes * * @param arr fill this array fully with data * @param page current page * @param curPageOff in (current) and out (new) parameter at index 0 * @param nextPage in (current) and out (new) parameter at index 0 * @return current page */ public int readMultiPageData(byte[] arr, int page, int[] curPageOff, int[] nextPage) throws IOException { int pageCounter = curPageOff[0]; int curNextPage = nextPage[0]; int curPage = page; int dct = 0; while (dct < arr.length) { int len = PAGESIZE - pageCounter; if (len <= 0) { if (curNextPage <= 0) throw new IOException("not enough pages to read data still need " + (arr.length - dct)); BlockFile.pageSeek(this.file, curNextPage); int magic = this.file.readInt(); if (magic != MAGIC_CONT) throw new IOException( "Bad SkipSpan continuation magic number 0x" + Integer.toHexString(magic) + " on page " + curNextPage); curPage = curNextPage; curNextPage = this.file.readUnsignedInt(); pageCounter = BSkipSpan.CONT_HEADER_LEN; len = PAGESIZE - pageCounter; } int res = this.file.read(arr, dct, Math.min(len, arr.length - dct)); if (res == -1) { throw new IOException(); } pageCounter += Math.min(len, arr.length - dct); dct += res; } nextPage[0] = curNextPage; curPageOff[0] = pageCounter; return curPage; }
/** * Run an integrity check on the blockfile and all the skiplists in it. * * <p>WARNING: This only works on skiplists using UTF8StringBytes as a key serializer, unless the * exception has been coded in bfck below. Will CORRUPT other skiplists. */ public static void main(String args[]) { if (args.length != 1) { System.err.println("Usage: BlockFile file"); return; } boolean init = !(new File(args[0])).exists(); try { RAIFile raif = new RAIFile(new File(args[0]), true, true); BlockFile bf = new BlockFile(raif, init); bf.bfck(true); bf.close(); raif.close(); } catch (Exception e) { e.printStackTrace(); } }
/** * Write bytes This will allocate additional continuation pages as necessary. * * @param data data to write * @param page current page * @param curPageOff in (current) and out (new) parameter at index 0 * @param nextPage in (current) and out (new) parameter at index 0 * @return current page */ public int writeMultiPageData(byte[] data, int page, int[] curPageOff, int[] nextPage) throws IOException { int pageCounter = curPageOff[0]; int curNextPage = nextPage[0]; int curPage = page; int dct = 0; while (dct < data.length) { int len = PAGESIZE - pageCounter; if (len <= 0) { if (curNextPage == 0) { curNextPage = this.allocPage(); BlockFile.pageSeek(this.file, curNextPage); this.file.writeInt(MAGIC_CONT); this.file.writeInt(0); BlockFile.pageSeek(this.file, curPage); this.file.skipBytes(4); // skip magic this.file.writeInt(curNextPage); } BlockFile.pageSeek(this.file, curNextPage); curPage = curNextPage; int magic = this.file.readInt(); if (magic != MAGIC_CONT) throw new IOException( "Bad SkipSpan continuation magic number 0x" + Integer.toHexString(magic) + " on page " + curNextPage); curNextPage = this.file.readUnsignedInt(); pageCounter = BSkipSpan.CONT_HEADER_LEN; len = PAGESIZE - pageCounter; } this.file.write(data, dct, Math.min(len, data.length - dct)); pageCounter += Math.min(len, data.length - dct); dct += Math.min(len, data.length - dct); } nextPage[0] = curNextPage; curPageOff[0] = pageCounter; return curPage; }