📄 cache.java
字号:
} catch (IOException e) { e.printStackTrace(); throw Trace.error(Trace.FILE_IO_ERROR, "reading: " + e); } return r; } /** * Reads a Row object from this Cache that corresponds to the * (pos) file offset in .data file. */ CachedRow getRow(int pos, Table t) throws SQLException { // HJB-2001-06-21 int k = (pos >> 3) & multiplierMask; CachedRow r = rData[k]; CachedRow start = r; int p = 0; while (r != null) { p = r.iPos; if (p == pos) { return r; } else if (((p >> 3) & multiplierMask) != k) { // HJB-2001-06-21 break; } r = r.rNext; if (r == start) { break; } } CachedRow before = rData[k]; if (before == null) { before = rFirst; } r = makeRow(pos, t); if (r != null) { r.insert(before); iCacheSize++; //-- iPos may have changed (blank lines). rData[(r.iPos >> 3) & multiplierMask] = r; rFirst = r; t.indexRow(r, false); } return r; } /** * Cleans up this Cache object. <p> * * This method is called when this Cache object grows too large. <p> * * Cleanup is done by checking the iLastAccess member of this * object's in-memory Rows and removing those that have * been least recently accessed (classic LRU algoritm). * */ void cleanUp() throws SQLException { if (iCacheSize < maxCacheSize) { return; } int count = 0; int j = 0; // HJB-2001-06-21 while ((j++ < cacheLength) && (iCacheSize > maxCacheSize / 2) && (count < writerLength)) { CachedRow r = getWorst(); if (r == null) { return; } if (r.hasChanged()) { // HJB-2001-06-21 // make sure that the row will not be added twice // getWorst() in some cases returns the same row many times /** * for (int i=0;i<count;i++) { if (rWriter[i]==r) { r=null; * break; } } if (r!=null) { rWriter[count++] = r; } */ r.iLastAccess = CachedRow.iCurrentAccess; rWriter[count++] = r; } else { // here we can't remove roots if (!r.isRoot()) { remove(r); } } } if (count != 0) { saveSorted(count); } for (int i = 0; i < count; i++) { // here we can't remove roots CachedRow r = rWriter[i]; if (!r.isRoot()) { remove(r); } rWriter[i] = null; } } /** * Removes a Row from this Cache object. * * <b>Note:</b> This method is called by the cleanUp method. */ protected void remove(CachedRow r) throws SQLException {/* if (Trace.DOASSERT) { Trace.doAssert(!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 // HJB-2001-06-21 int k = (r.iPos >> 3) & multiplierMask; if (rData[k] == r) { CachedRow n = r.rNext; rFirst = n; if (n == r || ((n.iPos >> 3) & multiplierMask) != k) { // HJB-2001-06-21 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--; } /** * Finds the Row with the smallest (oldest) iLastAccess member (LRU). <p> * * <b>Note:</b> This method is called by the cleanup method. */ private CachedRow getWorst() throws SQLException { if (rLastChecked == null) { rLastChecked = rFirst; } CachedRow r = rLastChecked; if (r == null) { return null; } CachedRow candidate = r; int worst = CachedRow.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; } /** * Writes out all cached Rows. * */ protected void saveAll() throws SQLException { if (rFirst == null) { return; } CachedRow r = rFirst; while (true) { int count = 0; CachedRow begin = r; do { if (Trace.STOP) { Trace.stop(); } if (r.hasChanged()) { rWriter[count++] = r; } r = r.rNext; } while (r != begin && count < writerLength); // HJB-2001-06-21 if (count == 0) { return; } saveSorted(count); for (int i = 0; i < count; i++) { rWriter[i] = null; } } } /** * Writes out the specified Row. */ protected void saveRow(CachedRow r) throws IOException, SQLException { rFile.seek(r.iPos); DatabaseRowOutputInterface out; if (newCacheType) { out = new BinaryServerRowOutput(r.storageSize); } else { out = new BinaryDatabaseRowOutput(r.storageSize); } r.write(out); rFile.write(out.toByteArray()); } /** * Writes out the first <code>count</code> rWriter Rows in iPos * sorted order. */ private void saveSorted(int count) throws SQLException { sort(rWriter, 0, count - 1); try { for (int i = 0; i < count; i++) { saveRow(rWriter[i]); } } catch (Exception e) { throw Trace.error(Trace.FILE_IO_ERROR, "saveSorted " + e); } } /** * FastQSorts the [l,r] partition of the specfied array of Rows, based on * the contained Row objects' iPos (file offset) values. * */ private static final void sort(CachedRow w[], int l, int r) throws SQLException { int i; int j; int 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(); } CachedRow t = w[i]; for (j = i - 1; j >= l && w[j].iPos > t.iPos; j--) { w[j + 1] = w[j]; } w[j + 1] = t; } } /** * Swaps the a'th and b'th elements of the specified Row array. */ private static void swap(CachedRow w[], int a, int b) { CachedRow t = w[a]; w[a] = w[b]; w[b] = t; } /** * Getter for iFreePos member */ int getFreePos() { return iFreePos; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -