introduced IOChunks.

This is an abstraction of chunked IO-processes.
It will help to synchronize access to IO-ports.
Furthermore this is a preparation for upcoming chunk-oriented write buffers.


git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@1201 6c8d7289-2bf4-0310-a012-ef5d649a1542
This commit is contained in:
orbiter 2005-12-11 02:36:49 +00:00
parent bb79fb5d91
commit ca7e60279d
8 changed files with 365 additions and 123 deletions

View File

@ -115,6 +115,8 @@ public class dbtest {
getTable().put(new byte[][] { entry.getKey(), entry.getValue() , entry.getValue() });
} catch (IOException e) {
System.err.println(e);
e.printStackTrace();
System.exit(0);
}
}
}
@ -139,6 +141,8 @@ public class dbtest {
}
} catch (IOException e) {
System.err.println(e);
e.printStackTrace();
System.exit(0);
}
}
}

View File

@ -0,0 +1,128 @@
// kelondroAbstractIOChunks.java
// -----------------------
// part of The Kelondro Database
// (C) by Michael Peter Christen; mc@anomic.de
// first published on http://www.anomic.de
// Frankfurt, Germany, 2005
// created: 11.12.2005
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Using this software in any meaning (reading, learning, copying, compiling,
// running) means that you agree that the Author(s) is (are) not responsible
// for cost, loss of data or any harm that may be caused directly or indirectly
// by usage of this softare or this documentation. The usage of this software
// is on your own risk. The installation and usage (starting/running) of this
// software may allow other people or application to access your computer and
// any attached devices and is highly dependent on the configuration of the
// software which must be done by the user of the software; the author(s) is
// (are) also not responsible for proper configuration and usage of the
// software, even if provoked by documentation provided together with
// the software.
//
// Any changes to this file according to the GPL as documented in the file
// gpl.txt aside this file in the shipment you received can be done to the
// lines that follows this copyright notice here, but changes must not be
// done inside the copyright notive above. A re-distribution must contain
// the intact and unchanged copyright notice.
// Contributions and changes to the program code must be marked as such.
package de.anomic.kelondro;
import java.io.IOException;
public abstract class kelondroAbstractIOChunks {
// logging support
protected String name = null;
public String name() {
return name;
}
// pseudo-native methods:
abstract public int read(long pos, byte[] b, int off, int len) throws IOException;
abstract public void write(long pos, byte[] b, int off, int len) throws IOException;
abstract public void close() throws IOException;
// derived methods:
public void readFully(long pos, byte[] b, int off, int len) throws IOException {
final int r = read(pos, b, off, len);
if (r < 0) return; // read exceeded EOF
if (r < len) {
pos += r;
readFully(pos, b, off + r, len - r);
}
}
public byte readByte(long pos) throws IOException {
byte[] b = new byte[1];
this.readFully(pos, b, 0, 1);
return b[0];
}
public void writeByte(long pos, final int v) throws IOException {
this.write(pos, new byte[]{(byte) (v & 0xFF)});
}
public short readShort(long pos) throws IOException {
byte[] b = new byte[2];
this.readFully(pos, b, 0, 2);
return (short) ((((int) b[0] & 0xFF) << 8) | (((int) b[1] & 0xFF) << 0));
}
public void writeShort(long pos, final int v) throws IOException {
this.write(pos, new byte[]{(byte) ((v >>> 8) & 0xFF), (byte) ((v >>> 0) & 0xFF)});
}
public int readInt(long pos) throws IOException {
byte[] b = new byte[4];
this.readFully(pos, b, 0, 4);
return (((int) b[0] & 0xFF) << 24) | (((int) b[1] & 0xFF) << 16) | (((int) b[2] & 0xFF) << 8) | ((int) b[3] & 0xFF);
}
public void writeInt(long pos, final int v) throws IOException {
this.write(pos, new byte[]{
(byte) ((v >>> 24) & 0xFF),
(byte) ((v >>> 16) & 0xFF),
(byte) ((v >>> 8) & 0xFF),
(byte) ((v >>> 0) & 0xFF)
});
}
public long readLong(long pos) throws IOException {
byte[] b = new byte[8];
this.readFully(pos, b, 0, 8);
return (((long) b[0] & 0xFF) << 56) | (((long) b[1] & 0xFF) << 48) | (((long) b[2]) << 40) | (((long) b[3] & 0xFF) << 32) | (((long) b[4] & 0xFF) << 24) | (((long) b[5] & 0xFF) << 16) | (((long) b[6] & 0xFF) << 8) | ((long) b[7] & 0xFF);
}
public void writeLong(long pos, final long v) throws IOException {
this.write(pos, new byte[]{
(byte) ((v >>> 56) & 0xFF),
(byte) ((v >>> 48) & 0xFF),
(byte) ((v >>> 40) & 0xFF),
(byte) ((v >>> 32) & 0xFF),
(byte) ((v >>> 24) & 0xFF),
(byte) ((v >>> 16) & 0xFF),
(byte) ((v >>> 8) & 0xFF),
(byte) ((v >>> 0) & 0xFF)
});
}
public void write(long pos, final byte[] b) throws IOException {
this.write(pos, b, 0, b.length);
}
}

View File

@ -90,7 +90,7 @@ abstract class kelondroAbstractRA implements kelondroRA {
final int ch1 = this.read();
final int ch2 = this.read();
if ((ch1 | ch2) < 0) throw new IOException();
return (short) ((ch1 << 8) + (ch2 << 0));
return (short) ((ch1 << 8) | (ch2 << 0));
}
public void writeShort(final int v) throws IOException {
@ -112,7 +112,7 @@ abstract class kelondroAbstractRA implements kelondroRA {
}
public long readLong() throws IOException {
return ((long) (readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
return ((long) (readInt()) << 32) | (readInt() & 0xFFFFFFFFL);
}
public void writeLong(final long v) throws IOException {

View File

@ -45,14 +45,12 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.FileDescriptor;
import java.util.Map;
import java.util.Properties;
public final class kelondroFileRA extends kelondroAbstractRA implements kelondroRA {
protected RandomAccessFile RAFile;
protected FileDescriptor RADescriptor;
public kelondroFileRA(String file) throws IOException, FileNotFoundException {
this(new File(file));
@ -60,20 +58,8 @@ public final class kelondroFileRA extends kelondroAbstractRA implements kelondro
public kelondroFileRA(File file) throws IOException, FileNotFoundException {
this.name = file.getName();
RAFile = new RandomAccessFile(file, "rw");
RADescriptor = RAFile.getFD();
RAFile = new RandomAccessFile(file, "rw");
}
/*
private void sync() throws IOException {
try {
RADescriptor.sync();
//try {Thread.currentThread().sleep(8);} catch (InterruptedException e) {return;}
} catch (SyncFailedException e) {
throw new IOException(e.getMessage());
}
}
*/
// pseudo-native method read
public int read() throws IOException {
@ -95,7 +81,7 @@ public final class kelondroFileRA extends kelondroAbstractRA implements kelondro
}
public void seek(long pos) throws IOException {
RAFile.seek(pos);
RAFile.seek(pos);
}
public void close() throws IOException {

View File

@ -0,0 +1,73 @@
// kelondroIOChunks.java
// -----------------------
// part of The Kelondro Database
// (C) by Michael Peter Christen; mc@anomic.de
// first published on http://www.anomic.de
// Frankfurt, Germany, 2005
// created: 11.12.2005
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Using this software in any meaning (reading, learning, copying, compiling,
// running) means that you agree that the Author(s) is (are) not responsible
// for cost, loss of data or any harm that may be caused directly or indirectly
// by usage of this softare or this documentation. The usage of this software
// is on your own risk. The installation and usage (starting/running) of this
// software may allow other people or application to access your computer and
// any attached devices and is highly dependent on the configuration of the
// software which must be done by the user of the software; the author(s) is
// (are) also not responsible for proper configuration and usage of the
// software, even if provoked by documentation provided together with
// the software.
//
// Any changes to this file according to the GPL as documented in the file
// gpl.txt aside this file in the shipment you received can be done to the
// lines that follows this copyright notice here, but changes must not be
// done inside the copyright notive above. A re-distribution must contain
// the intact and unchanged copyright notice.
// Contributions and changes to the program code must be marked as such.
package de.anomic.kelondro;
import java.io.IOException;
public interface kelondroIOChunks {
// logging support
public String name();
// pseudo-native methods:
public int read(long pos, byte[] b, int off, int len) throws IOException;
public void write(long pos, byte[] b, int off, int len) throws IOException;
public void commit() throws IOException;
public void close() throws IOException;
// derived methods:
public void readFully(long pos, byte[] b, int off, int len) throws IOException;
public byte readByte(long pos) throws IOException;
public void writeByte(long pos, int v) throws IOException;
public short readShort(long pos) throws IOException;
public void writeShort(long pos, int v) throws IOException;
public int readInt(long pos) throws IOException;
public void writeInt(long pos, int v) throws IOException;
public long readLong(long pos) throws IOException;
public void writeLong(long pos, long v) throws IOException;
public void write(long pos, byte[] b) throws IOException;
}

View File

@ -64,13 +64,13 @@ public interface kelondroRA {
public void write(int b) throws IOException;
public int read(byte[] b, int off, int len) throws IOException;
public void readFully(byte[] b, int off, int len) throws IOException;
public void write(byte[] b, int off, int len) throws IOException;
public void seek(long pos) throws IOException;
public void close() throws IOException;
// derivated methods:
// derived methods:
public void readFully(byte[] b, int off, int len) throws IOException;
public byte readByte() throws IOException;
public void writeByte(int v) throws IOException;

View File

@ -0,0 +1,84 @@
// kelondroRAIOChunks.java
// -----------------------
// part of The Kelondro Database
// (C) by Michael Peter Christen; mc@anomic.de
// first published on http://www.anomic.de
// Frankfurt, Germany, 2005
// created: 1.12.2004
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Using this software in any meaning (reading, learning, copying, compiling,
// running) means that you agree that the Author(s) is (are) not responsible
// for cost, loss of data or any harm that may be caused directly or indirectly
// by usage of this softare or this documentation. The usage of this software
// is on your own risk. The installation and usage (starting/running) of this
// software may allow other people or application to access your computer and
// any attached devices and is highly dependent on the configuration of the
// software which must be done by the user of the software; the author(s) is
// (are) also not responsible for proper configuration and usage of the
// software, even if provoked by documentation provided together with
// the software.
//
// Any changes to this file according to the GPL as documented in the file
// gpl.txt aside this file in the shipment you received can be done to the
// lines that follows this copyright notice here, but changes must not be
// done inside the copyright notive above. A re-distribution must contain
// the intact and unchanged copyright notice.
// Contributions and changes to the program code must be marked as such.
package de.anomic.kelondro;
import java.io.IOException;
public final class kelondroRAIOChunks extends kelondroAbstractIOChunks implements kelondroIOChunks {
protected kelondroRA ra;
public kelondroRAIOChunks(kelondroRA ra, String name) {
this.name = name;
this.ra = ra;
}
public int read(long pos, byte[] b, int off, int len) throws IOException {
synchronized (this.ra) {
this.ra.seek(pos);
return ra.read(b, off, len);
}
}
public void write(long pos, byte[] b, int off, int len) throws IOException {
synchronized (this.ra) {
this.ra.seek(pos);
this.ra.write(b, off, len);
}
}
public void commit() throws IOException {
// do nothing here
// this method is used to flush write-buffers
}
public void close() throws IOException {
if (this.ra != null) this.ra.close();
this.ra = null;
}
protected void finalize() throws Throwable {
if (this.ra != null) this.close();
super.finalize();
}
}

View File

@ -118,7 +118,7 @@ public class kelondroRecords {
// values that are only present at run-time
protected String filename; // the database's file name
protected kelondroRA entryFile; // the database file
protected kelondroIOChunks entryFile; // the database file
private int overhead; // OHBYTEC + 4 * OHHANDLEC = size of additional control bytes
private int headchunksize;// overheadsize + key element column size
private int tailchunksize;// sum(all: COLWIDTHS) minus the size of the key element colum
@ -169,17 +169,17 @@ public class kelondroRecords {
public void write() throws IOException {
synchronized (entryFile) {
entryFile.seek(POS_USEDC); entryFile.writeInt(USEDC);
entryFile.seek(POS_FREEC); entryFile.writeInt(FREEC);
entryFile.seek(POS_FREEH); entryFile.writeInt(FREEH.index);
entryFile.writeInt(POS_USEDC, USEDC);
entryFile.writeInt(POS_FREEC, FREEC);
entryFile.writeInt(POS_FREEH, FREEH.index);
}
}
public void read() throws IOException {
synchronized (entryFile) {
entryFile.seek(POS_USEDC); this.USEDC = entryFile.readInt();
entryFile.seek(POS_FREEC); this.FREEC = entryFile.readInt();
entryFile.seek(POS_FREEH); this.FREEH = new Handle(entryFile.readInt());
this.USEDC = entryFile.readInt(POS_USEDC);
this.FREEC = entryFile.readInt(POS_FREEC);
this.FREEH = new Handle(entryFile.readInt(POS_FREEH));
}
}
@ -218,12 +218,13 @@ public class kelondroRecords {
private void init(kelondroRA ra, short ohbytec, short ohhandlec,
int[] columns, int FHandles, int txtProps, int txtPropWidth) throws IOException {
// create new Chunked IO
this.entryFile = new kelondroRAIOChunks(ra, ra.name());
// store dynamic run-time data
this.entryFile = ra;
this.overhead = ohbytec + 4 * ohhandlec;
this.recordsize = this.overhead;
for (int i = 0; i < columns.length; i++)
this.recordsize += columns[i];
for (int i = 0; i < columns.length; i++) this.recordsize += columns[i];
this.headchunksize = overhead + columns[0];
this.tailchunksize = this.recordsize - this.headchunksize;
@ -244,37 +245,35 @@ public class kelondroRecords {
TXTPROPW = txtPropWidth;
// write data to file
entryFile.seek(POS_MAGIC); entryFile.writeByte(4); // magic marker for this file type
entryFile.seek(POS_BUSY); entryFile.writeByte(0); // unlock: default
entryFile.seek(POS_PORT); entryFile.writeShort(4444); // default port (not used yet)
entryFile.seek(POS_DESCR); entryFile.write("--AnomicRecords file structure--".getBytes());
entryFile.seek(POS_COLUMNS); entryFile.writeShort(this.COLWIDTHS.length);
entryFile.seek(POS_OHBYTEC); entryFile.writeShort(OHBYTEC);
entryFile.seek(POS_OHHANDLEC); entryFile.writeShort(OHHANDLEC);
entryFile.seek(POS_USEDC); entryFile.writeInt(this.USAGE.USEDC);
entryFile.seek(POS_FREEC); entryFile.writeInt(this.USAGE.FREEC);
entryFile.seek(POS_FREEH); entryFile.writeInt(this.USAGE.FREEH.index);
entryFile.seek(POS_MD5PW); entryFile.write("PASSWORDPASSWORD".getBytes());
entryFile.seek(POS_ENCRYPTION); entryFile.write("ENCRYPTION!#$%&?".getBytes());
entryFile.seek(POS_OFFSET); entryFile.writeLong(POS_NODES);
entryFile.seek(POS_INTPROPC); entryFile.writeInt(FHandles);
entryFile.seek(POS_TXTPROPC); entryFile.writeInt(txtProps);
entryFile.seek(POS_TXTPROPW); entryFile.writeInt(txtPropWidth);
entryFile.writeByte(POS_MAGIC, 4); // magic marker for this file type
entryFile.writeByte(POS_BUSY, 0); // unlock: default
entryFile.writeShort(POS_PORT, 4444); // default port (not used yet)
entryFile.write(POS_DESCR, "--AnomicRecords file structure--".getBytes());
entryFile.writeShort(POS_COLUMNS, this.COLWIDTHS.length);
entryFile.writeShort(POS_OHBYTEC, OHBYTEC);
entryFile.writeShort(POS_OHHANDLEC, OHHANDLEC);
entryFile.writeInt(POS_USEDC, this.USAGE.USEDC);
entryFile.writeInt(POS_FREEC, this.USAGE.FREEC);
entryFile.writeInt(POS_FREEH, this.USAGE.FREEH.index);
entryFile.write(POS_MD5PW, "PASSWORDPASSWORD".getBytes());
entryFile.write(POS_ENCRYPTION, "ENCRYPTION!#$%&?".getBytes());
entryFile.writeLong(POS_OFFSET, POS_NODES);
entryFile.writeInt(POS_INTPROPC, FHandles);
entryFile.writeInt(POS_TXTPROPC, txtProps);
entryFile.writeInt(POS_TXTPROPW, txtPropWidth);
// write configuration arrays
for (int i = 0; i < this.COLWIDTHS.length; i++) {
entryFile.seek(POS_COLWIDTHS + 4 * i);
entryFile.writeInt(COLWIDTHS[i]);
entryFile.writeInt(POS_COLWIDTHS + 4 * i, COLWIDTHS[i]);
}
for (int i = 0; i < this.HANDLES.length; i++) {
entryFile.seek(POS_HANDLES + 4 * i);
entryFile.writeInt(NUL);
entryFile.writeInt(POS_HANDLES + 4 * i, NUL);
HANDLES[i] = new Handle(NUL);
}
byte[] ea = new byte[TXTPROPW];
for (int j = 0; j < TXTPROPW; j++) ea[j] = 0;
for (int i = 0; i < this.TXTPROPS.length; i++) {
entryFile.seek(POS_TXTPROPS + TXTPROPW * i);
for (int j = 0; j < TXTPROPW; j++)
entryFile.writeByte(0);
entryFile.write(POS_TXTPROPS + TXTPROPW * i, ea);
}
}
@ -319,20 +318,20 @@ public class kelondroRecords {
}
private void init(kelondroRA ra) throws IOException {
// assign values that are only present at run-time
this.entryFile = ra;
// read from Chunked IO
this.entryFile = new kelondroRAIOChunks(ra, ra.name());
// read dynamic variables that are back-ups of stored values in file;
// read/defined on instantiation
this.USAGE = new usageControl();
entryFile.seek(POS_OHBYTEC); this.OHBYTEC = entryFile.readShort();
entryFile.seek(POS_OHHANDLEC); this.OHHANDLEC = entryFile.readShort();
this.OHBYTEC = entryFile.readShort(POS_OHBYTEC);
this.OHHANDLEC = entryFile.readShort(POS_OHHANDLEC);
entryFile.seek(POS_COLUMNS); this.COLWIDTHS = new int[entryFile.readShort()];
entryFile.seek(POS_INTPROPC); this.HANDLES = new Handle[entryFile.readInt()];
entryFile.seek(POS_TXTPROPC); this.TXTPROPS = new byte[entryFile.readInt()][];
entryFile.seek(POS_TXTPROPW); this.TXTPROPW = entryFile.readInt();
this.COLWIDTHS = new int[entryFile.readShort(POS_COLUMNS)];
this.HANDLES = new Handle[entryFile.readInt(POS_INTPROPC)];
this.TXTPROPS = new byte[entryFile.readInt(POS_TXTPROPC)][];
this.TXTPROPW = entryFile.readInt(POS_TXTPROPW);
if (COLWIDTHS.length == 0) throw new kelondroException(filename, "init: zero columns; strong failure");
@ -343,17 +342,14 @@ public class kelondroRecords {
// read configuration arrays
for (int i = 0; i < COLWIDTHS.length; i++) {
entryFile.seek(POS_COLWIDTHS + 4 * i);
COLWIDTHS[i] = entryFile.readInt();
COLWIDTHS[i] = entryFile.readInt(POS_COLWIDTHS + 4 * i);
}
for (int i = 0; i < HANDLES.length; i++) {
entryFile.seek(POS_HANDLES + 4 * i);
HANDLES[i] = new Handle(entryFile.readInt());
HANDLES[i] = new Handle(entryFile.readInt(POS_HANDLES + 4 * i));
}
for (int i = 0; i < TXTPROPS.length; i++) {
entryFile.seek(POS_TXTPROPS + TXTPROPW * i);
TXTPROPS[i] = new byte[TXTPROPW];
entryFile.readFully(TXTPROPS[i], 0, TXTPROPS[i].length);
entryFile.readFully(POS_TXTPROPS + TXTPROPW * i, TXTPROPS[i], 0, TXTPROPS[i].length);
}
// assign remaining values that are only present at run-time
@ -553,10 +549,7 @@ public class kelondroRecords {
// read overhead and key
//System.out.println("**NO CACHE for " + this.handle.index + "**");
this.headChunk = new byte[headchunksize];
synchronized (entryFile) {
entryFile.seek(seekpos(this.handle));
entryFile.readFully(this.headChunk, 0, this.headChunk.length);
}
entryFile.readFully(seekpos(this.handle), this.headChunk, 0, this.headChunk.length);
this.headChanged = false;
} else synchronized(XcacheHeaders) {
byte[] cacheEntry = null;
@ -575,11 +568,8 @@ public class kelondroRecords {
//System.out.println("**CACHE miss for " + this.handle.index + "**");
this.headChunk = new byte[headchunksize];
//this.tailChunk = new byte[tailchunksize];
synchronized (entryFile) {
entryFile.seek(seekpos(this.handle));
entryFile.readFully(this.headChunk, 0, this.headChunk.length);
//entryFile.readFully(this.tailChunk, 0, this.tailChunk.length);
}
entryFile.readFully(seekpos(this.handle), this.headChunk, 0, this.headChunk.length);
this.headChanged = true; // provoke a cache store
cp = CP_HIGH;
if (OHHANDLEC == 3) {
@ -682,10 +672,7 @@ public class kelondroRecords {
// load all values from the database file
this.tailChunk = new byte[tailchunksize];
// read values
synchronized (entryFile) {
entryFile.seek(seekpos(this.handle) + headchunksize);
entryFile.readFully(this.tailChunk, 0, this.tailChunk.length);
}
entryFile.readFully(seekpos(this.handle) + headchunksize, this.tailChunk, 0, this.tailChunk.length);
}
// create return value
@ -717,21 +704,14 @@ public class kelondroRecords {
// save head
if (this.headChanged) {
synchronized (entryFile) {
entryFile.seek(seekpos(this.handle));
// System.out.print("#write "); printChunk(this.handle,
// this.headChunk); System.out.println();
entryFile.write(this.headChunk);
}
entryFile.write(seekpos(this.handle), this.headChunk);
update2Cache(cachePriority);
}
// save tail
if ((this.tailChunk != null) && (this.tailChanged))
synchronized (entryFile) {
entryFile.seek(seekpos(this.handle) + headchunksize);
entryFile.write(this.tailChunk);
}
if ((this.tailChunk != null) && (this.tailChanged)) {
entryFile.write(seekpos(this.handle) + headchunksize, this.tailChunk);
}
}
public synchronized void collapse() {
@ -898,10 +878,10 @@ public class kelondroRecords {
for (int i = 0; i < size() + 3; i++) {
// print from file to compare
System.out.print("#F " + i + ": ");
try {synchronized (entryFile) {
entryFile.seek(seekpos(new Handle(i)));
for (int j = 0; j < headchunksize; j++) System.out.print(entryFile.readByte() + ",");
}} catch (IOException e) {}
try {
for (int j = 0; j < headchunksize; j++)
System.out.print(entryFile.readByte(j + seekpos(new Handle(i))) + ",");
} catch (IOException e) {}
System.out.println();
}
@ -920,10 +900,10 @@ public class kelondroRecords {
// print from file to compare
System.out.print("#F " + cp + " " + ((Handle) entry.getKey()).index + ": ");
try {synchronized (entryFile) {
entryFile.seek(seekpos((Handle) entry.getKey()));
for (int j = 0; j < headchunksize; j++) System.out.print(entryFile.readByte() + ",");
}} catch (IOException e) {}
try {
for (int j = 0; j < headchunksize; j++)
System.out.print(entryFile.readByte(j + seekpos((Handle) entry.getKey())) + ",");
} catch (IOException e) {}
System.out.println();
}
@ -960,11 +940,8 @@ public class kelondroRecords {
protected void setHandle(int pos, Handle handle) throws IOException {
if (pos >= HANDLES.length) throw new IllegalArgumentException("setHandle: handle array exceeded");
if (handle == null) handle = new Handle(NUL);
synchronized (entryFile) {
HANDLES[pos] = handle;
entryFile.seek(POS_HANDLES + 4 * pos);
entryFile.writeInt(handle.index);
}
HANDLES[pos] = handle;
entryFile.writeInt(POS_HANDLES + 4 * pos, handle.index);
}
protected Handle getHandle(int pos) {
@ -977,11 +954,8 @@ public class kelondroRecords {
if (pos >= TXTPROPS.length) throw new IllegalArgumentException("setText: text array exceeded");
if (text.length > TXTPROPW) throw new IllegalArgumentException("setText: text lemgth exceeded");
if (text == null) text = new byte[0];
synchronized (entryFile) {
TXTPROPS[pos] = text;
entryFile.seek(POS_TXTPROPS + TXTPROPW * pos);
entryFile.write(text);
}
TXTPROPS[pos] = text;
entryFile.write(POS_TXTPROPS + TXTPROPW * pos, text);
}
public byte[] getText(int pos) {
@ -1010,13 +984,10 @@ public class kelondroRecords {
synchronized (USAGE) {
USAGE.USEDC--;
USAGE.FREEC++;
synchronized (entryFile) {
// change pointer
entryFile.seek(seekpos(h));
entryFile.writeInt(USAGE.FREEH.index); // extend free-list
// write new FREEH Handle link
USAGE.FREEH = h;
}
// change pointer
entryFile.writeInt(seekpos(h), USAGE.FREEH.index); // extend free-list
// write new FREEH Handle link
USAGE.FREEH = h;
USAGE.write();
}
}
@ -1152,9 +1123,7 @@ public class kelondroRecords {
// generate new entry
index = USAGE.allCount();
USAGE.USEDC++;
synchronized (entryFile) {
entryFile.seek(POS_USEDC); entryFile.writeInt(USAGE.USEDC);
}
entryFile.writeInt(POS_USEDC, USAGE.USEDC);
} else {
// re-use record from free-list
USAGE.USEDC++;
@ -1168,10 +1137,8 @@ public class kelondroRecords {
index = USAGE.USEDC - 1;
} else {
index = USAGE.FREEH.index;
synchronized (entryFile) {
// read link to next element to FREEH chain
entryFile.seek(seekpos(USAGE.FREEH)); USAGE.FREEH.index = entryFile.readInt();
}
// read link to next element to FREEH chain
USAGE.FREEH.index = entryFile.readInt(seekpos(USAGE.FREEH));
}
USAGE.write();
}