Skip to content

Commit

Permalink
- removed object cache from kelondroTree
Browse files Browse the repository at this point in the history
- generalized object caching and added new object caching class
- added object caching wherever kelondroTree was used
- added object caching also to usage of kelondroFlex
- added object buffering (a write cache) to NURLs
- added many assert statements; fixed bugs here and there
- added missing close methods to latest added classes

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@2858 6c8d7289-2bf4-0310-a012-ef5d649a1542
  • Loading branch information
orbiter committed Oct 24, 2006
1 parent 7299dc3 commit 2a9d868
Show file tree
Hide file tree
Showing 40 changed files with 619 additions and 272 deletions.
4 changes: 2 additions & 2 deletions htroot/PerformanceMemory_p.java
Expand Up @@ -49,7 +49,7 @@

import de.anomic.http.httpHeader;
import de.anomic.http.httpc;
import de.anomic.kelondro.kelondroTree;
import de.anomic.kelondro.kelondroCachedIndex;
import de.anomic.plasma.plasmaSwitchboard;
import de.anomic.server.serverFileUtils;
import de.anomic.server.serverMemory;
Expand Down Expand Up @@ -338,7 +338,7 @@ public static serverObjects respond(httpHeader header, serverObjects post, serve

private static void putprop(serverObjects prop, serverSwitch env, String wdb, String db, String set) {
if ((slt == null) || (ost == null)) return;
usd = chk * slt[1] + obj * ost[2] /*hit*/ + kelondroTree.cacheObjectMissSize * ost[3] /*miss*/;
usd = chk * slt[1] + obj * ost[2] /*hit*/ + kelondroCachedIndex.cacheObjectMissSize * ost[3] /*miss*/;
bst = (((((long) chk) * ((long) req)) >> 10) + 1) << 10;
if (set.equals("setBest")) env.setConfig("ramCache" + db, bst);
prop.put(wdb + ((wdb.length() > 0) ? ("_") : ("")) + "nodsz" + db, chk);
Expand Down
4 changes: 2 additions & 2 deletions htroot/PerformanceQueues_p.html
Expand Up @@ -76,10 +76,10 @@ <h2>Performance Settings of Queues and Processes</h2>
<td>Description</td>
</tr>
<tr valign="top" class="TableCellDark">
<td>URLs in RAM cache:</td>
<td>URLs in RAM buffer:</td>
<td colspan="2" align="center">#[urlCacheSize]#</td>
<td>
This is the size of the URL cache. Its purpose is to buffer incoming URLs
This is the size of the URL write buffer. Its purpose is to buffer incoming URLs
in case of search result transmission and during DHT transfer.
</td>
</tr>
Expand Down
20 changes: 19 additions & 1 deletion source/dbtest.java
Expand Up @@ -13,6 +13,7 @@
import java.util.Random;

import de.anomic.kelondro.kelondroBase64Order;
import de.anomic.kelondro.kelondroCachedIndex;
import de.anomic.kelondro.kelondroFlexSplitTable;
import de.anomic.kelondro.kelondroFlexTable;
import de.anomic.kelondro.kelondroIndex;
Expand Down Expand Up @@ -174,7 +175,7 @@ public static void main(String[] args) {
kelondroRow testRow = new kelondroRow("byte[] key-" + keylength + ", byte[] dummy-" + keylength + ", value-" + valuelength);
if (dbe.equals("kelondroTree")) {
File tablefile = new File(tablename + ".kelondro.db");
table = new kelondroTree(tablefile, buffer, preload, kelondroTree.defaultObjectCachePercent, testRow);
table = new kelondroCachedIndex(new kelondroTree(tablefile, buffer / 2, preload, testRow), buffer / 2);
}
if (dbe.equals("kelondroSplittedTree")) {
File tablepath = new File(tablename).getParentFile();
Expand Down Expand Up @@ -616,6 +617,23 @@ public kelondroProfile profile() {
return new kelondroProfile();
}

public final int cacheObjectChunkSize() {
// dummy method
return -1;
}

public long[] cacheObjectStatus() {
// dummy method
return null;
}

public final int cacheNodeChunkSize() {
return -1;
}

public final int[] cacheNodeStatus() {
return new int[]{0,0,0,0,0,0,0,0,0,0};
}
}


Expand Down
4 changes: 2 additions & 2 deletions source/de/anomic/kelondro/kelondroBase64Order.java
Expand Up @@ -298,9 +298,9 @@ public final int compares(byte[] a, int aoffset, int alength, byte[] b, int boff
bc = b[boffset + i];
assert (bc >= 0) && (bc < 128) : "bc = " + bc + ", b = " + serverLog.arrayList(b, boffset, len);
acc = ahpla[ac];
assert (acc >= 0) : "acc = " + acc + ", a = " + serverLog.arrayList(a, aoffset, len);
assert (acc >= 0) : "acc = " + acc + ", a = " + serverLog.arrayList(a, aoffset, len) + ", aoffset = " + aoffset + serverLog.table(a, aoffset);
bcc = ahpla[bc];
assert (bcc >= 0) : "bcc = " + bcc + ", b = " + serverLog.arrayList(b, boffset, len);
assert (bcc >= 0) : "bcc = " + bcc + ", b = " + serverLog.arrayList(b, boffset, len) + ", boffset = " + boffset + serverLog.table(b, boffset);
if (acc > bcc) return 1;
if (acc < bcc) return -1;
// else the bytes are equal and it may go on yet undecided
Expand Down
27 changes: 26 additions & 1 deletion source/de/anomic/kelondro/kelondroBufferedIndex.java
Expand Up @@ -33,6 +33,7 @@
import java.util.TreeMap;

import de.anomic.server.serverMemory;
import de.anomic.server.logging.serverLog;

public class kelondroBufferedIndex implements kelondroIndex {

Expand All @@ -50,7 +51,7 @@ public kelondroBufferedIndex(kelondroIndex theIndex) {
}

public synchronized void flush() throws IOException {
if (buffer.size() == 0) return;
if ((buffer == null) || (buffer.size() == 0)) return;
Iterator i = buffer.entrySet().iterator();
Map.Entry entry;
while (i.hasNext()) {
Expand Down Expand Up @@ -103,6 +104,9 @@ public synchronized kelondroRow.Entry put(kelondroRow.Entry row) throws IOExcept
}

public synchronized kelondroRow.Entry put(kelondroRow.Entry row, Date entryDate) throws IOException {
assert (row != null);
assert (row.getColBytes(index.primarykey()) != null);
assert (!(serverLog.allZero(row.getColBytes(index.primarykey()))));
long handle = (index instanceof kelondroFlexSplitTable) ? -1 : index.profile().startWrite();
byte[] key = row.getColBytes(index.primarykey());
kelondroRow.Entry oldentry = null;
Expand Down Expand Up @@ -211,4 +215,25 @@ public synchronized Iterator rows(boolean up, boolean rotating, byte[] firstKey)
public static kelondroBufferedIndex getRAMIndex(kelondroRow rowdef, int initSize) {
return new kelondroBufferedIndex(new kelondroRowSet(rowdef, kelondroNaturalOrder.naturalOrder, 0, initSize));
}

public final int cacheObjectChunkSize() {
// dummy method
return -1;
}

public long[] cacheObjectStatus() {
// dummy method
return null;
}

public final int cacheNodeChunkSize() {
// returns the size that the node cache uses for a single entry
return index.cacheNodeChunkSize();
}

public final int[] cacheNodeStatus() {
// a collection of different node cache status values
return index.cacheNodeStatus();
}

}
14 changes: 14 additions & 0 deletions source/de/anomic/kelondro/kelondroBytesIntMap.java
Expand Up @@ -27,6 +27,8 @@
import java.io.IOException;
import java.util.Iterator;

import de.anomic.server.logging.serverLog;

public class kelondroBytesIntMap {

private kelondroIndex ki;
Expand All @@ -38,12 +40,16 @@ public kelondroBytesIntMap(kelondroIndex ki) throws IOException {
}

public synchronized int geti(byte[] key) throws IOException {
assert (key != null);
assert (!(serverLog.allZero(key)));
kelondroRow.Entry indexentry = ki.get(key);
if (indexentry == null) return -1;
return (int) indexentry.getColLong(1);
}

public synchronized int puti(byte[] key, int i) throws IOException {
assert (key != null);
assert (!(serverLog.allZero(key)));
kelondroRow.Entry newentry = ki.row().newEntry();
newentry.setCol(0, key);
newentry.setCol(1, i);
Expand All @@ -53,13 +59,17 @@ public synchronized int puti(byte[] key, int i) throws IOException {
}

public synchronized void addi(byte[] key, int i) throws IOException {
assert (key != null);
assert (!(serverLog.allZero(key)));
kelondroRow.Entry newentry = ki.row().newEntry();
newentry.setCol(0, key);
newentry.setCol(1, i);
ki.addUnique(newentry);
}

public synchronized int removei(byte[] key) throws IOException {
assert (key != null);
assert (!(serverLog.allZero(key)));
// returns the integer index of the key, if the key can be found and was removed
// and -1 if the key was not found.
if (ki.size() == 0) return -1;
Expand Down Expand Up @@ -94,4 +104,8 @@ public kelondroProfile profile() {
return ki.profile();
}

public synchronized void close() throws IOException {
ki.close();
}

}
151 changes: 151 additions & 0 deletions source/de/anomic/kelondro/kelondroCachedIndex.java
@@ -0,0 +1,151 @@
// kelondroCachedIndex
// (C) 2006 by Michael Peter Christen; mc@anomic.de, Frankfurt a. M., Germany
// first published 23.10.2006 on http://www.anomic.de
//
// $LastChangedDate: 2006-04-02 22:40:07 +0200 (So, 02 Apr 2006) $
// $LastChangedRevision: 1986 $
// $LastChangedBy: orbiter $
//
// LICENSE
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package de.anomic.kelondro;

import java.io.IOException;
import java.util.Date;
import java.util.Iterator;

import de.anomic.kelondro.kelondroRow.Entry;
import de.anomic.server.logging.serverLog;

public class kelondroCachedIndex implements kelondroIndex {

public final static int cacheObjectMissSize = 120;
public final static int defaultObjectCachePercent = 10;

private kelondroObjectCache objectCache;
private kelondroIndex theIndex;

public kelondroCachedIndex(kelondroIndex superIndex, long objectbuffersize) throws IOException {
this.theIndex = superIndex;
long objecthitcachesize = objectbuffersize * 4 / 5 / cacheObjectChunkSize();
long objectmisscachesize = objectbuffersize / 5 / cacheObjectMissSize;
this.objectCache = new kelondroObjectCache("generic", (int) objecthitcachesize, (int) objectmisscachesize, objecthitcachesize * 3000 , 4*1024*1024);
}

public final int cacheObjectChunkSize() {
try {
return this.theIndex.row().objectsize() + /* overhead */ 16 * this.theIndex.row().columns();
} catch (IOException e) {
return 0;
}
}

public long[] cacheObjectStatus() {
if (this.objectCache == null) return null;
return this.objectCache.status();
}

public final int cacheNodeChunkSize() {
// returns the size that the node cache uses for a single entry
return theIndex.cacheNodeChunkSize();
}

public final int[] cacheNodeStatus() {
// a collection of different node cache status values
return theIndex.cacheNodeStatus();
}

public void addUnique(Entry row) throws IOException {
// the use case for add implies that usually the objects are not needed in the cache
// therefore omit an object cache write here
this.theIndex.addUnique(row);
}

public void addUnique(Entry row, Date entryDate) throws IOException {
this.theIndex.addUnique(row, entryDate);
}

public void close() throws IOException {
this.objectCache = null;
this.theIndex.close();

}

public Entry get(byte[] key) throws IOException {
// get result from cache
kelondroRow.Entry result = (objectCache == null) ? null : (kelondroRow.Entry) objectCache.get(key);
if (result != null) return result;
// check if we have an entry in the miss cache
if ((objectCache != null) && (objectCache.has(key) == -1)) return null;
// finally: get it from the index
result = this.theIndex.get(key);
if (result == null) objectCache.hasnot(key); else objectCache.put(key, result);
return result;
}

public kelondroOrder order() {
return this.theIndex.order();
}

public int primarykey() {
return this.theIndex.primarykey();
}

public kelondroProfile profile() {
return this.theIndex.profile();
}

public Entry put(Entry row) throws IOException {
assert (row != null);
assert (row.columns() == row().columns());
assert (!(serverLog.allZero(row.getColBytes(theIndex.primarykey()))));
objectCache.put(row.getColBytes(theIndex.primarykey()), row);
return this.theIndex.put(row);
}

public Entry put(Entry row, Date entryDate) throws IOException {
assert (row.columns() == row().columns());
objectCache.put(row.getColBytes(theIndex.primarykey()), row);
return this.theIndex.put(row, entryDate);
}

public Entry remove(byte[] key) throws IOException {
if (objectCache.has(key) == -1) return null;
objectCache.remove(key);
return this.theIndex.remove(key);
}

public Entry removeOne() throws IOException {
Entry entry = this.theIndex.removeOne();
if (entry == null) return null;
this.objectCache.remove(entry.getColBytes(this.theIndex.primarykey()));
return entry;
}

public kelondroRow row() throws IOException {
return this.theIndex.row();
}

public Iterator rows(boolean up, boolean rotating, byte[] firstKey) throws IOException {
return this.theIndex.rows(up, rotating, firstKey);
}

public int size() throws IOException {
return this.theIndex.size();
}

}
2 changes: 1 addition & 1 deletion source/de/anomic/kelondro/kelondroCollectionIndex.java
Expand Up @@ -177,7 +177,7 @@ private kelondroIndex openIndexFile(File path, String filenameStub, kelondroOrde
long buffersize, long preloadTime,
int loadfactor, kelondroRow rowdef) throws IOException {
// open/create index table
kelondroFlexTable theindex = new kelondroFlexTable(path, filenameStub + ".index", buffersize, preloadTime, indexRow(), indexOrder);
kelondroIndex theindex = new kelondroCachedIndex(new kelondroFlexTable(path, filenameStub + ".index", buffersize / 2, preloadTime, indexRow(), indexOrder), buffersize / 2);

// save/check property file for this array
File propfile = propertyFile(path, filenameStub, loadfactor, rowdef.objectsize());
Expand Down

0 comments on commit 2a9d868

Please sign in to comment.