Prevent integer overflow in table statistics and use strong typing

pull/122/head
luccioman 8 years ago
parent 0f80c978d6
commit 0487336ec3

@ -38,6 +38,7 @@ import net.yacy.cora.protocol.RequestHeader;
import net.yacy.cora.util.ConcurrentLog; import net.yacy.cora.util.ConcurrentLog;
import net.yacy.kelondro.index.RAMIndex; import net.yacy.kelondro.index.RAMIndex;
import net.yacy.kelondro.table.Table; import net.yacy.kelondro.table.Table;
import net.yacy.kelondro.table.Table.TableStatistics;
import net.yacy.kelondro.util.Formatter; import net.yacy.kelondro.util.Formatter;
import net.yacy.kelondro.util.MemoryControl; import net.yacy.kelondro.util.MemoryControl;
import net.yacy.search.Switchboard; import net.yacy.search.Switchboard;
@ -124,27 +125,23 @@ public class PerformanceMemory_p {
// write table for Table index sizes // write table for Table index sizes
Iterator<String> i = Table.filenames(); Iterator<String> i = Table.filenames();
String filename; String filename;
Map<Table.StatKeys, String> mapx; TableStatistics stats;
int p; int p;
c = 0; c = 0;
long mem, totalmem = 0; long totalmem = 0;
while (i.hasNext()) { while (i.hasNext()) {
filename = i.next(); filename = i.next();
mapx = Table.memoryStats(filename); stats = Table.memoryStats(filename);
totalmem += stats.getTotalMem();
prop.put("EcoList_" + c + "_tableIndexPath", ((p = filename.indexOf("DATA",0)) < 0) ? filename : filename.substring(p)); prop.put("EcoList_" + c + "_tableIndexPath", ((p = filename.indexOf("DATA",0)) < 0) ? filename : filename.substring(p));
prop.putNum("EcoList_" + c + "_tableSize", mapx.get(Table.StatKeys.tableSize)); prop.putNum("EcoList_" + c + "_tableSize", stats.getTableSize());
String v = mapx.get(Table.StatKeys.tableKeyMem); prop.put("EcoList_" + c + "_tableKeyMem", Formatter.bytesToString(stats.getKeyMem()));
mem = v == null ? 0 : Long.parseLong(v); prop.put("EcoList_" + c + "_tableKeyChunkSize", Formatter.bytesToString(stats.getKeyChunkSize()));
totalmem += mem;
prop.put("EcoList_" + c + "_tableKeyMem", Formatter.bytesToString(mem));
prop.put("EcoList_" + c + "_tableKeyChunkSize", mapx.get(Table.StatKeys.tableKeyChunkSize));
v = mapx.get(Table.StatKeys.tableValueMem); prop.put("EcoList_" + c + "_tableValueMem", Formatter.bytesToString(stats.getValueMem()));
mem = v == null ? 0 : Long.parseLong(v); prop.put("EcoList_" + c + "_tableValueChunkSize", Formatter.bytesToString(stats.getValueChunkSize()));
totalmem += mem;
prop.put("EcoList_" + c + "_tableValueMem", Formatter.bytesToString(mem));
prop.put("EcoList_" + c + "_tableValueChunkSize", mapx.get(Table.StatKeys.tableValueChunkSize));
c++; c++;
} }
@ -154,7 +151,6 @@ public class PerformanceMemory_p {
// write object cache table // write object cache table
final Iterator<Map.Entry<String, RAMIndex>> oi = RAMIndex.objects(); final Iterator<Map.Entry<String, RAMIndex>> oi = RAMIndex.objects();
c = 0; c = 0;
mem = 0;
Map.Entry<String, RAMIndex> oie; Map.Entry<String, RAMIndex> oie;
RAMIndex cache; RAMIndex cache;
long hitmem, totalhitmem = 0; long hitmem, totalhitmem = 0;

@ -31,7 +31,6 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.ConcurrentModificationException; import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -72,6 +71,8 @@ public class Table implements Index, Iterable<Row.Entry> {
// static tracker objects // static tracker objects
private final static ConcurrentLog log = new ConcurrentLog("TABLE"); private final static ConcurrentLog log = new ConcurrentLog("TABLE");
/** Map all active table instances by file name */
private final static TreeMap<String, Table> tableTracker = new TreeMap<String, Table>(); private final static TreeMap<String, Table> tableTracker = new TreeMap<String, Table>();
private final static long maxarraylength = 134217727L; // (2^27-1) that may be the maximum size of array length in some JVMs private final static long maxarraylength = 134217727L; // (2^27-1) that may be the maximum size of array length in some JVMs
@ -363,7 +364,7 @@ public class Table implements Index, Iterable<Row.Entry> {
return tableTracker.keySet().iterator(); return tableTracker.keySet().iterator();
} }
public static final Map<StatKeys, String> memoryStats(final String filename) { public static final TableStatistics memoryStats(final String filename) {
// returns a map for each file in the tracker; // returns a map for each file in the tracker;
// the map represents properties for each record objects, // the map represents properties for each record objects,
// i.e. for cache memory allocation // i.e. for cache memory allocation
@ -371,23 +372,89 @@ public class Table implements Index, Iterable<Row.Entry> {
return theTABLE.memoryStats(); return theTABLE.memoryStats();
} }
public enum StatKeys { /**
tableSize, tableKeyChunkSize, tableKeyMem, tableValueChunkSize, tableValueMem * Table memory usage statistics
*/
public class TableStatistics {
/** The table entries number */
private int tableSize = 0;
/** Size of a key chunk in bytes */
private int keyChunkSize = 0;
/** Total size of keys in bytes */
private long keyMem = 0;
/** Size of a value chunk in bytes */
private int valueChunkSize = 0;
/** Total size of values in bytes */
private long valueMem = 0;
/**
* @return the size of a key chunk in bytes
*/
public int getKeyChunkSize() {
return this.keyChunkSize;
} }
private final Map<StatKeys, String> memoryStats() { /**
* @return the total size of the table in-memory keys in bytes
*/
public long getKeyMem() {
return this.keyMem;
}
/**
* @return the table entries number
*/
public int getTableSize() {
return this.tableSize;
}
/**
* @return the size of a value chunk in bytes
*/
public int getValueChunkSize() {
return this.valueChunkSize;
}
/**
* @return the total size of the table in-memory values in bytes
*/
public long getValueMem() {
return this.valueMem;
}
/**
* @return the total memory used by the table in bytes
*/
public long getTotalMem() {
return this.keyMem + this.valueMem;
}
}
/**
* @return computed table current memory usage statistics
*/
private final TableStatistics memoryStats() {
// returns statistical data about this object // returns statistical data about this object
synchronized (this) { synchronized (this) {
assert this.table == null || this.table.size() == this.index.size() : "table.size() = " + this.table.size() + ", index.size() = " + this.index.size(); assert this.table == null || this.table.size() == this.index.size() : "table.size() = " + this.table.size() + ", index.size() = " + this.index.size();
} }
final HashMap<StatKeys, String> map = new HashMap<StatKeys, String>(8); TableStatistics stats = new TableStatistics();
if (this.index == null) return map; // possibly closed or beeing closed if (this.index == null) return stats; // possibly closed or being closed
map.put(StatKeys.tableSize, Integer.toString(this.index.size())); stats.tableSize = this.index.size();
map.put(StatKeys.tableKeyChunkSize, (this.index instanceof RowHandleMap) ? Integer.toString(((RowHandleMap) this.index).row().objectsize) : "-1"); if(this.index instanceof RowHandleMap) {
map.put(StatKeys.tableKeyMem, (this.index instanceof RowHandleMap) ? Integer.toString(((RowHandleMap) this.index).row().objectsize * this.index.size()) : "-1"); stats.keyChunkSize = (((RowHandleMap) this.index).row().objectsize);
map.put(StatKeys.tableValueChunkSize, (this.table == null) ? "0" : Integer.toString(this.table.row().objectsize)); stats.keyMem = (long)((RowHandleMap) this.index).row().objectsize * (long)this.index.size();
map.put(StatKeys.tableValueMem, (this.table == null) ? "0" : Integer.toString(this.table.row().objectsize * this.table.size())); }
return map; if(table != null) {
stats.valueChunkSize = this.table.row().objectsize;
stats.valueMem = (long)this.table.row().objectsize * (long)this.table.size();
}
return stats;
} }
public boolean usesFullCopy() { public boolean usesFullCopy() {

Loading…
Cancel
Save