Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

database lock

 
bin jian
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi!
here is one thouble which i encountered when preparing for the SCJD exam,i tried to find anything will be helpful after knew the assignment of this certification contains implementing one raw database system as its part,and i read the book "java algorithms" by Scott Robert Ladd,in the chapter 11 of that book,Scott figure out the problem how to store Object into one binary file,the whole codes is presented as follows:
import java.io.*;
public class ObjectDatabaseFile
{
/*-------------------------------------------------------
constants
-------------------------------------------------------*/
protected static final long DEL_LIST_END = -1;
private static final byte IS_DELETED = 0;
private static final byte IS_ACTIVE = 1;
/*-------------------------------------------------------
fields
-------------------------------------------------------*/
protected RandomAccessFile dataFile;
private String fileName;
protected long firstDel;//the header position of deleted link list;

/*-------------------------------------------------------
constructors
-------------------------------------------------------*/
public ObjectDatabaseFile(String name) throws IOException
{
fileName = new String(name);
dataFile = new RandomAccessFile(name,"rw");
constructorHelper();
}
public ObjectDatabaseFile(File file) throws IOException
{
fileName = new String(file.getName());
dataFile = new RandomAccessFile(file,"rw");
constructorHelper();
}
private void constructorHelper() throws IOException
{
//check for new file;
if(dataFile.length() == 0)
{
dataFile.writeLong(DEL_LIST_END);
firstDel = DEL_LIST_END;
}
else
firstDel = dataFile.readLong();
}
/*-------------------------------------------------------
implement object I/O
-------------------------------------------------------*/
//write object to current position;
public long writeObject(Object obj) throws IOException
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
ObjectOutputStream ostrm =new ObjectOutputStream(bytes);
ostrm.writeObject(obj);
ostrm.flush();

int datalen = bytes.size();
int reclen = datalen;
long pos;//beginning of rec header;
//find someplace to put the record;
if(firstDel == DEL_LIST_END)
{
//find end of the file;
pos = dataFile.length();
//move to end of the file;
dataFile.seek(pos);
}
else
{
//start with first deleted record
long prev = DEL_LIST_END;

pos = firstDel;
while(true)
{
dataFile.seek(pos);
byte deleted = dataFile.readByte();
dataFile.readInt();
reclen = dataFile.readInt();
long next = dataFile.readLong();
//check integrity
if (deleted == IS_ACTIVE)
throw new IOException("corrupt delete list");
//is deleted record is enough for new data?
if(reclen >= datalen)
{
if(prev == DEL_LIST_END)
{
//change file header deletion mark;
firstDel = next;

//write new deleted record# at beginning of file;
dataFile.seek(0);
dataFile.writeLong(firstDel);
}
else//go back to previous record;
{
dataFile.seek(prev+1+4+4);
dataFile.writeLong(next);
}
dataFile.seek(pos);
break;
}
//deleted record is too small,go to next;
prev = pos;
//do we have any more deleted records in the chain?
if(next == DEL_LIST_END)
{
//append to end of file;
pos = dataFile.length();
dataFile.seek(pos);
break;
}
else
pos = next;
}
}
//write record into file;
dataFile.writeByte(IS_ACTIVE);
dataFile.writeInt(datalen);
dataFile.writeInt(reclen);
dataFile.writeLong(DEL_LIST_END);
dataFile.write(bytes.toByteArray());
//return length of output;
return pos;
}

//read object from current record;
public Object readObject() throws IOException,ClassNotFoundException
{
while(true)
{
byte deleted = dataFile.readByte();
if(deleted == IS_ACTIVE)
break;
dataFile.skipBytes(4);
int n = dataFile.readInt();
dataFile.skipBytes(n+8);
}
int datalen = dataFile.readInt();
int reclen = dataFile.readInt();
dataFile.skipBytes(8);
byte[] data = new byte[datalen];
dataFile.readFully(data);
int diff = reclen - datalen;
if(diff>0)
dataFile.skipBytes(diff);
ByteArrayInputStream bytes = new ByteArrayInputStream(data);
ObjectInputStream istrm = new ObjectInputStream(bytes);
return istrm.readObject();
}
//delete the current object record;
public void delete() throws IOException
{
long pos = dataFile.getFilePointer();
byte deleted = dataFile.readByte();
if(deleted == IS_DELETED)
return;
dataFile.seek(pos);
dataFile.writeByte(IS_DELETED);
dataFile.skipBytes(4+4);
dataFile.writeLong(firstDel);
firstDel = pos;
dataFile.seek(0);
dataFile.writeLong(firstDel);
}
//go to the beginning of file;
public void rewind() throws IOException
{
dataFile.seek(8);
}
//skip over an object record;
public void skip() throws IOException
{
dataFile.skipBytes(1+4);
int reclen = dataFile.readInt();
dataFile.skipBytes(8+reclen);
}
//compact file by removing deleted records;
public void compact(ObjectDatabaseCallback callback) throws IOException,Throwable
{
File tempName = new File("TMP"+System.currentTimeMillis());
RandomAccessFile newFile = new RandomAccessFile(tempName,"rw");
newFile.writeLong(DEL_LIST_END);
while(true)
{
try
{
byte deleted = dataFile.readByte();
int datalen = dataFile.readInt();
int reclen = dataFile.readInt();
if(deleted == IS_DELETED)
{
dataFile.skipBytes(8+reclen);
}
else
{
dataFile.skipBytes(8);
byte[] data = new byte[datalen];
dataFile.readFully(data);
int diff = reclen-datalen;
if(diff>0)
dataFile.skipBytes(diff);
long pos = newFile.getFilePointer();
newFile.writeByte(IS_ACTIVE);
newFile.writeInt(datalen);
newFile.writeInt(reclen);
newFile.writeLong(DEL_LIST_END);
newFile.write(data);
ByteArrayInputStream bytes = new ByteArrayInputStream(data);
ObjectInputStream istrm = new ObjectInputStream(bytes);
if(callback != null)
callback.compactNotify(pos,istrm.readObject());
}
}
catch(EOFException eof)
{
break;
}
catch(Throwable ex)
{
throw ex;
}
}
dataFile.close();
File goAway = new File(fileName);
goAway.delete();
newFile.close();
tempName.renameTo(new File(fileName));
dataFile = new RandomAccessFile(fileName,"rw");
constructorHelper();
}
/*-------------------------------------------------------
provide shells for RandomAccessFile methods
-------------------------------------------------------*/
public final FileDescriptor getFD() throws IOException
{
return dataFile.getFD();
}
public long getFilePointer() throws IOException
{
return dataFile.getFilePointer();
}
public void seek(long pos) throws IOException
{
dataFile.seek(pos);
}
public long length() throws IOException
{
return dataFile.length();
}
public void close() throws IOException
{
dataFile.close();
}
}
but further more,after a second thought,i am conscious of another problem,how can this approach admit the synchronization of each record?indeed,i can not find anything can be done to satisfy this requirement.
i believe this is quite an interesting problem.then now whether you guys can figure out something more about this problem by your experience.
any suggestion will be appreciated!
good luck!

bin jian
[ February 03, 2002: Message edited by: bin jian ]
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My suggestion would be not to worry about the code of an author that isn't related to the Developer exam. It is similar, but you do not have to do what he did. You already have the Data, DataInfo, and FieldInfo classes designed for you correctly. All you have to do is fix the two deprecated calls, and either extend or modify the Data class to include lock, unlock and criteriaFind.
Mark
 
bin jian
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanx mark,
i believe i clear now,actually need not think so much.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic