📄 spanningblockfile.java
字号:
public byte[] get(int rrn)
throws IOException{
Mapping m = getMapping(rrn);
byte b[] = new byte[m.size];
int offset = 0;
for(int i = 0; i < m.count; i++){
offset += readBytes(m.ptrs[i], b, offset);
}
return b;
}
/**
* Return number of blocks allocated for a given relative record
* number 'rrn'
*
* @param rrn relative record number
* @return number of blocks allocated for 'rrn'
*/
public int getRecordBlockCount(int rrn) {
Mapping m = getMapping(rrn);
if (m == null)
return 0;
return m.count;
}
/**
* Return number of data bytes written for a given relative record
* number 'rrn', i.e the total number of bytes of data.
*
* @param rrn relative record number
* @return number of data bytes
*/
public int getRecordSize(int rrn) {
Mapping m = getMapping(rrn);
if (m == null)
return 0;
return m.size;
}
/**
* Deletes a record from this file and frees the previously blocks for
* reuse.
* @param rrn the record to delete.
*/
public void delete(int rrn){
Mapping m = (Mapping) mapping.remove(new Integer(rrn));
if(m == null)
return;
for(int i = 0; i < m.count; i++){
putDeletedBlock(m.ptrs[i]);
}
}
/**
* Sets the length of a record. This can result in either that new blocks
* will be added to the record or old blocks deleted and marked for reuse.
*
* @param rrn a recored number
* @param newLength the new length
*/
public void setLength(int rrn, int newLength){
Mapping m = getMapping(rrn);
int oldSize = m.size;
m.size = newLength;
int i = getCount(m.size);
if(i < m.count){ //now delete some records if possible
for(i = getCount(m.size);i < m.count; i++){
putDeletedBlock(m.ptrs[i]);
}
m.count = getCount(m.size);
}
else if(i > m.count){ //increase if nessecary:
while(m.count < i){
if(m.ptrs.length == m.count)
growPointers(m);
m.ptrs[m.count] = getNextBlock();
m.count++;
}
}
}
/**
* Defragments this file.
*/
public void defragment(){
}
/**
* Prints the header information of this file.
*/
public String toString(){
StringBuffer sbuff = new StringBuffer();
sbuff.append("\n\nFile name: "+fileName+"\n");
sbuff.append("block size: "+blockSize+"\n");
sbuff.append("deleted blocks: ");
for(int i = 0; i < deletedBlocks; i++)
sbuff.append(dBlocks[i]+" ");
sbuff.append("\nMapping: ");
Mapping m;
Integer rrn;
for(Iterator i = mapping.keySet().iterator(); i.hasNext();){
rrn = (Integer) i.next();
m = (Mapping) mapping.get(rrn);
sbuff.append("Logical Block: "+rrn+" size: "+m.size+" physical pointers: ");
for(int j = 0; j < m.count; j++){
sbuff.append(m.ptrs[j]+" ");
}
sbuff.append("\n\n");
}
return sbuff.toString();
}
/***************************PRIVATE SECTION******************/
private Mapping getMapping(int rrn){
Integer i = new Integer(rrn);
return (Mapping) mapping.get(i);
}
private void growPointers(Mapping m){
int[] tmp = new int[m.ptrs.length * 2];
System.arraycopy(m.ptrs, 0, tmp, 0, m.ptrs.length);
m.ptrs = tmp;
}
private int getDeletedBlock(){
if(deletedBlocks == 0)
return -1;
deletedBlocks--;
int block = dBlocks[deletedBlocks];
return block;
}
private int getCount(int size){
return (size % blockSize)==0?
size/blockSize:(size/blockSize)+1;
}
private void putDeletedBlock(int block){
if(deletedBlocks == dBlocks.length){
int[] tmp = new int[dBlocks.length * 2];
System.arraycopy(dBlocks, 0, tmp, 0, dBlocks.length);
dBlocks = tmp;
}
dBlocks[deletedBlocks] = block;
deletedBlocks++;
}
private int getNextBlock(){
if(deletedBlocks == 0){
highPBlock++;
return highPBlock - 1;
}
return getDeletedBlock();
}
private int writeBytes(int blockNo, byte[] b, int offset, int fOffset,
int length)
throws IOException{
file.seek((blockNo * blockSize)+fOffset);
int free = blockSize - fOffset;
int toWrite = (offset + blockSize) <= length?blockSize:
length - offset;
//calculate actual size:
if(toWrite > free)
toWrite = free;
//System.out.println("toWrite: "+toWrite);
file.write(b, offset, toWrite);
return toWrite;
}
private int writeBytes(int blockNo, byte[] b, int offset, int length)
throws IOException{
return writeBytes(blockNo, b, offset, 0, length);
}
private int readBytes(int blockNo, byte[] b, int offset)
throws IOException{
file.seek(blockNo * blockSize);
int toRead = (offset + blockSize) <= b.length?blockSize:
b.length - offset;
file.readFully(b, offset, toRead);
return toRead;
}
/**
* Tries to close the file if it is open
*
*/
protected void finalize(){
try{
closeFile();
}
catch(IOException e){System.out.println(e);}
}
/*********************************INNER CLASSES**************************/
class Mapping{
int[] ptrs = new int[10];
int count = 0;
int size;
}
class SBFIterator implements Iterator{
Iterator mapIterator = mapping.values().iterator();
public boolean hasNext(){
return mapIterator.hasNext();
}
public Object next(){
try{
Mapping m = (Mapping) mapIterator.next();
byte b[] = new byte[m.size];
int offset = 0;
for(int i = 0; i < m.count; i++){
offset += readBytes(m.ptrs[i], b, offset);
}
return b;
}
catch(IOException e){
throw new NoSuchElementException();
}
}
public void remove(){
throw new UnsupportedOperationException();
}
}
class MappingIterator implements Iterator{
Iterator iterator;
MapEntry me;
Map.Entry realEntry;
ByteStorable mTemplate;
public MappingIterator(Integer startFrom, ByteStorable template){
iterator = mapping.tailMap(startFrom).entrySet().iterator();
me = new MapEntry();
mTemplate = template;
}
public MappingIterator(ByteStorable template){
iterator = mapping.entrySet().iterator();
me = new MapEntry();
mTemplate = template;
}
public boolean hasNext(){
return iterator.hasNext();
}
public Object next(){
try{
realEntry = (Map.Entry) iterator.next();
Mapping m = (Mapping) realEntry.getValue();
byte b[] = new byte[m.size];
int offset = 0;
for(int i = 0; i < m.count; i++){
offset += readBytes(m.ptrs[i], b, offset);
}
me.k = realEntry.getKey();
if(mTemplate == null)
me.v = b;
else
me.v = mTemplate.fromBytes(b, 0);
return me;
}
catch(IOException e){
throw new NoSuchElementException();
}
}
public void remove(){
throw new UnsupportedOperationException();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -