⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spanningblockfile.java

📁 实现数据库的storage manager 功能
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
  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 + -