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

📄 cache.java

📁 一个可以在applet窗体上持行sql语句并显示返回结果的程序
💻 JAVA
字号:
/*
 * Cache.java
 */

package org.hsql;
import java.io.*;
import java.sql.*;

class Cache {
  private RandomAccessFile rFile;
  private final static int LENGTH=1<<14;
  private final static int MAX_CACHE_SIZE=LENGTH*3/4;
  private Row rData[];
  private Row rWriter[];
  private Row rFirst;  // must point to one of rData[]
  private Row rLastChecked; // can be any row
  private String sName;
  private final static int MASK=(LENGTH)-1;
  private int iFreePos;
  private final static int FREE_POS_POS=16; // where iFreePos is saved
  private final static int INITIAL_FREE_POS=32;
  private final static int MAX_FREE_COUNT=1024;
  private CacheFree fRoot;
  private int iFreeCount;
  private int iCacheSize;

  Cache(String name) {
    sName=name;
    rData=new Row[LENGTH];
    rWriter=new Row[LENGTH];
  }
  void open(boolean readonly) throws SQLException {
    try {
      boolean exists=false;
      File f=new File(sName);
      if(f.exists() && f.length()>FREE_POS_POS) {
        exists=true;
      }
      rFile=new RandomAccessFile(sName,readonly ? "r" : "rw");
      if(exists) {
        rFile.seek(FREE_POS_POS);
        iFreePos=rFile.readInt();
      } else {
        iFreePos=INITIAL_FREE_POS;
      }
    } catch(Exception e) {
      throw Trace.error(Trace.FILE_IO_ERROR,"error "+e+" opening "+sName);
    }
  }
  void flush() throws SQLException {
    try {
      rFile.seek(FREE_POS_POS);
      rFile.writeInt(iFreePos);
      saveAll();
      rFile.close();
    } catch(Exception e) {
      throw Trace.error(Trace.FILE_IO_ERROR,"error "+e+" closing "+sName);
    }
  }
  void shutdown() throws SQLException {
    try {
      rFile.close();
    } catch(Exception e) {
      throw Trace.error(Trace.FILE_IO_ERROR,"error "+e+" in shutdown "+sName);
    }
  }
  void free(Row r,int pos,int length) throws SQLException {
    iFreeCount++;
    CacheFree n=new CacheFree();
    n.iPos=pos;
    n.iLength=length;
    // if more than MAX_FREE_COUNT free positios then probably
    // all are too small anyway; so start a new list
    // todo: this is wrong when deleting lots of records
    if(iFreeCount>MAX_FREE_COUNT) {
      iFreeCount=0;
    } else {
      n.fNext=fRoot;
    }
    fRoot=n;
    // it's possible to remove roots to
    remove(r);
  }
  void add(Row r) throws SQLException {
    int size=r.iSize;
    CacheFree f=fRoot;
    CacheFree last=null;
    int i=iFreePos;
    while(f!=null) {
      if(Trace.TRACE) Trace.stop();
      // first that is long enough
      if(f.iLength>=size) {
        i=f.iPos;
        size=f.iLength-size;
        if(size<8) {
          // remove almost empty blocks
          if(last==null) {
            fRoot=f.fNext;
          } else {
            last.fNext=f.fNext;
          }
          iFreeCount--;
        } else {
          f.iLength=size;
        }
        break;
      }
      last=f;
      f=f.fNext;
    }
    r.iPos=i;
    if(i==iFreePos) {
      iFreePos+=size;
    }
    int k=i&MASK;
    Row before=rData[k];
    if(before==null) {
      before=rFirst;
    }
    r.insert(before);
    iCacheSize++;
    rData[k]=r;
    rFirst=r;
  }
  Row getRow(int pos,Table t) throws SQLException {
    int k=pos&MASK;
    Row r=rData[k];
    Row start=r;
    while(r!=null) {
      if(Trace.STOP) Trace.stop();
      int p=r.iPos;
      if(p==pos) {
        return r;
      } else if((p&MASK) != k) {
        break;
      }
      r=r.rNext;
      if(r==start) {
        break;
      }
    }
    Row before=rData[k];
    if(before==null) {
      before=rFirst;
    }
    try {
      rFile.seek(pos);
      int size=rFile.readInt();
      byte buffer[]=new byte[size];
      rFile.read(buffer);
      ByteArrayInputStream bin=new ByteArrayInputStream(buffer);
      DataInputStream in=new DataInputStream(bin);
      r=new Row(t,in,pos,before);
      r.iSize=size;
    } catch(IOException e) {
      e.printStackTrace();
      throw Trace.error(Trace.FILE_IO_ERROR,"reading: "+e);
    }
    // todo: copy & paste here
    iCacheSize++;
    rData[k]=r;
    rFirst=r;
    return r;
  }
  void cleanUp() throws SQLException {
    if(iCacheSize<MAX_CACHE_SIZE) {
      return;
    }
    int count=0,j=0;
    while(j++<LENGTH && iCacheSize+LENGTH>MAX_CACHE_SIZE && (count*16)<LENGTH) {
      if(Trace.STOP) Trace.stop();
      Row r=getWorst();
      if(r==null) {
        return;
      }
      if(r.bChanged) {
        rWriter[count++]=r;
      } else {
        // here we can't remove roots
        if(!r.canRemove()) {
          remove(r);
        }
      }
    }
    if(count!=0) {
      saveSorted(count);
    }
    for(int i=0;i<count;i++) {
      // here we can't remove roots
      Row r=rWriter[i];
      if(!r.canRemove()) {
        remove(r);
      }
      rWriter[i]=null;
    }
  }
  private void remove(Row r) throws SQLException {
    if(Trace.ASSERT) Trace.assert(!r.bChanged);
    // make sure rLastChecked does not point to r
    if(r==rLastChecked) {
      rLastChecked=rLastChecked.rNext;
      if(rLastChecked==r) {
        rLastChecked=null;
      }
    }
    // make sure rData[k] does not point here
    int k=r.iPos&MASK;
    if(rData[k]==r) {
      Row n=r.rNext;
      rFirst=n;
      if(n==r || (n.iPos&MASK)!=k) {
        n=null;
      }
      rData[k]=n;
    }
    // make sure rFirst does not point here
    if(r==rFirst) {
      rFirst=rFirst.rNext;
      if(r==rFirst) {
        rFirst=null;
      }
    }
    r.free();
    iCacheSize--;
  }
  private Row getWorst() throws SQLException {
    if(rLastChecked==null) {
      rLastChecked=rFirst;
    }
    Row r=rLastChecked;
    if(r==null) {
      return null;
    }
    Row candidate=r;
    int worst=Row.iCurrentAccess;
    // algorithm: check the next rows and take the worst
    for(int i=0;i<6;i++) {
      int w=r.iLastAccess;
      if(w<worst) {
        candidate=r;
        worst=w;
      }
      r=r.rNext;
    }
    rLastChecked=r.rNext;
    return candidate;
  }
  private void saveAll() throws SQLException {
    if(rFirst==null) {
      return;
    }
    Row r=rFirst;
    while(true) {
      int count=0;
      Row begin=r;
      do {
        if(Trace.STOP) Trace.stop();
        if(r.bChanged) {
          rWriter[count++]=r;
        }
        r=r.rNext;
      } while(r!=begin && count<LENGTH);
      if(count==0) {
        return;
      }
      saveSorted(count);
      for(int i=0;i<count;i++) {
        rWriter[i]=null;
      }
    }
  }
  private void saveSorted(int count) throws SQLException {
    sort(rWriter,0,count-1);
    try {
      for(int i=0;i<count;i++) {
        rFile.seek(rWriter[i].iPos);
        rFile.write(rWriter[i].write());
      }
    } catch(Exception e) {
      throw Trace.error(Trace.FILE_IO_ERROR,"saveSorted "+e);
    }
  }
  private static final void sort(Row w[],int l,int r) throws SQLException {
    int i,j,p;
    while(r-l>10) {
      i=(r+l)>>1;
      if(w[l].iPos>w[r].iPos) {
        swap(w,l,r);
      }
      if(w[i].iPos<w[l].iPos) {
        swap(w,l,i);
      } else if(w[i].iPos>w[r].iPos) {
        swap(w,i,r);
      }
      j=r-1;
      swap(w,i,j);
      p=w[j].iPos;
      i=l;
      while(true) {
        if(Trace.STOP) Trace.stop();
        while(w[++i].iPos<p);
        while(w[--j].iPos>p);
        if(i>=j) {
          break;
        }
        swap(w,i,j);
      }
      swap(w,i,r-1);
      sort(w,l,i-1);
      l=i+1;
    }
    for(i=l+1;i<=r;i++) {
      if(Trace.STOP) Trace.stop();
      Row t=w[i];
      for(j=i-1;j>=l && w[j].iPos>t.iPos;j--) {
        w[j+1]=w[j];
      }
      w[j+1]=t;
    }
  }
  private static void swap(Row w[],int a,int b) {
    Row t=w[a];
    w[a]=w[b];
    w[b]=t;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -