- this class is replaced by an object that can hold any type of object - this object must be defined as a class that implements kelondroObjectsEntry - the kelodroMap is now implemented as kelondroMapObjects git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@3297 6c8d7289-2bf4-0310-a012-ef5d649a1542pull/1/head
parent
214a18dea7
commit
9c05e2a820
@ -1,398 +1,291 @@
|
|||||||
// kelondroMap.java
|
// kelondroMapObjects.java
|
||||||
// -----------------------
|
// -----------------------
|
||||||
// part of The Kelondro Database
|
// (C) 29.01.2007 by Michael Peter Christen; mc@anomic.de, Frankfurt a. M., Germany
|
||||||
// (C) by Michael Peter Christen; mc@anomic.de
|
// first published 2004 as part of kelondroMap on http://www.anomic.de
|
||||||
// first published on http://www.anomic.de
|
//
|
||||||
// Frankfurt, Germany, 2004
|
// This is a part of YaCy, a peer-to-peer based web search engine
|
||||||
//
|
//
|
||||||
// $LastChangedDate$
|
// $LastChangedDate: 2006-04-02 22:40:07 +0200 (So, 02 Apr 2006) $
|
||||||
// $LastChangedRevision$
|
// $LastChangedRevision: 1986 $
|
||||||
// $LastChangedBy$
|
// $LastChangedBy: orbiter $
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// LICENSE
|
||||||
// it under the terms of the GNU General Public License as published by
|
//
|
||||||
// the Free Software Foundation; either version 2 of the License, or
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// (at your option) any later version.
|
// it under the terms of the GNU General Public License as published by
|
||||||
//
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
// This program is distributed in the hope that it will be useful,
|
// (at your option) any later version.
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
//
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// This program is distributed in the hope that it will be useful,
|
||||||
// GNU General Public License for more details.
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
//
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// You should have received a copy of the GNU General Public License
|
// GNU General Public License for more details.
|
||||||
// along with this program; if not, write to the Free Software
|
//
|
||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
// You should have received a copy of the GNU General Public License
|
||||||
//
|
// along with this program; if not, write to the Free Software
|
||||||
// Using this software in any meaning (reading, learning, copying, compiling,
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
// running) means that you agree that the Author(s) is (are) not responsible
|
|
||||||
// for cost, loss of data or any harm that may be caused directly or indirectly
|
package de.anomic.kelondro;
|
||||||
// by usage of this softare or this documentation. The usage of this software
|
|
||||||
// is on your own risk. The installation and usage (starting/running) of this
|
import java.io.IOException;
|
||||||
// software may allow other people or application to access your computer and
|
import java.util.HashMap;
|
||||||
// any attached devices and is highly dependent on the configuration of the
|
import java.util.Iterator;
|
||||||
// software which must be done by the user of the software; the author(s) is
|
import java.util.Map;
|
||||||
// (are) also not responsible for proper configuration and usage of the
|
|
||||||
// software, even if provoked by documentation provided together with
|
public class kelondroMapObjects extends kelondroObjects {
|
||||||
// the software.
|
|
||||||
//
|
private String[] sortfields, accfields;
|
||||||
// Any changes to this file according to the GPL as documented in the file
|
private HashMap sortClusterMap; // a String-kelondroMScoreCluster - relation
|
||||||
// gpl.txt aside this file in the shipment you received can be done to the
|
private HashMap accMap; // to store accumulations of specific fields
|
||||||
// lines that follows this copyright notice here, but changes must not be
|
private int elementCount;
|
||||||
// done inside the copyright notive above. A re-distribution must contain
|
|
||||||
// the intact and unchanged copyright notice.
|
public kelondroMapObjects(kelondroDyn dyn, int cachesize) {
|
||||||
// Contributions and changes to the program code must be marked as such.
|
this(dyn, cachesize, null, null);
|
||||||
|
}
|
||||||
package de.anomic.kelondro;
|
|
||||||
|
public kelondroMapObjects(kelondroDyn dyn, int cachesize, String[] sortfields, String[] accfields) {
|
||||||
import java.io.IOException;
|
super(dyn, cachesize);
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
// create fast ordering clusters and acc fields
|
||||||
import java.util.Map;
|
this.sortfields = sortfields;
|
||||||
|
this.accfields = accfields;
|
||||||
public class kelondroMap {
|
|
||||||
|
kelondroMScoreCluster[] cluster = null;
|
||||||
private static final int cachesize = 500;
|
if (sortfields == null) sortClusterMap = null; else {
|
||||||
|
sortClusterMap = new HashMap();
|
||||||
private kelondroDyn dyn;
|
cluster = new kelondroMScoreCluster[sortfields.length];
|
||||||
private kelondroMScoreCluster cacheScore;
|
for (int i = 0; i < sortfields.length; i++) {
|
||||||
private HashMap cache;
|
cluster[i] = new kelondroMScoreCluster();
|
||||||
private long startup;
|
}
|
||||||
private String[] sortfields, accfields;
|
}
|
||||||
private HashMap sortClusterMap; // a String-kelondroMScoreCluster - relation
|
|
||||||
private HashMap accMap; // to store accumulations of specific fields
|
Long[] accumulator = null;
|
||||||
private int elementCount;
|
if (accfields == null) accMap = null; else {
|
||||||
|
accMap = new HashMap();
|
||||||
public kelondroMap(kelondroDyn dyn) {
|
accumulator = new Long[accfields.length];
|
||||||
this(dyn, null, null);
|
for (int i = 0; i < accfields.length; i++) {
|
||||||
}
|
accumulator[i] = new Long(0);
|
||||||
|
}
|
||||||
public kelondroMap(kelondroDyn dyn, String[] sortfields, String[] accfields) {
|
}
|
||||||
this.dyn = dyn;
|
|
||||||
this.cache = new HashMap();
|
// fill cluster and accumulator with values
|
||||||
this.cacheScore = new kelondroMScoreCluster();
|
if ((sortfields != null) || (accfields != null)) try {
|
||||||
this.startup = System.currentTimeMillis();
|
kelondroDyn.dynKeyIterator it = dyn.dynKeys(true, false);
|
||||||
this.elementCount = 0;
|
String key, value;
|
||||||
|
long valuel;
|
||||||
// create fast ordering clusters and acc fields
|
Map map;
|
||||||
this.sortfields = sortfields;
|
while (it.hasNext()) {
|
||||||
this.accfields = accfields;
|
key = (String) it.next();
|
||||||
|
map = getMap(key);
|
||||||
kelondroMScoreCluster[] cluster = null;
|
if (map == null) break;
|
||||||
if (sortfields == null) sortClusterMap = null; else {
|
|
||||||
sortClusterMap = new HashMap();
|
if (sortfields != null) for (int i = 0; i < sortfields.length; i++) {
|
||||||
cluster = new kelondroMScoreCluster[sortfields.length];
|
value = (String) map.get(sortfields[i]);
|
||||||
for (int i = 0; i < sortfields.length; i++) {
|
if (value != null) cluster[i].setScore(key, kelondroMScoreCluster.string2score(value));
|
||||||
cluster[i] = new kelondroMScoreCluster();
|
}
|
||||||
}
|
|
||||||
}
|
if (accfields != null) for (int i = 0; i < accfields.length; i++) {
|
||||||
|
value = (String) map.get(accfields[i]);
|
||||||
Long[] accumulator = null;
|
if (value != null) try {
|
||||||
if (accfields == null) accMap = null; else {
|
valuel = Long.parseLong(value);
|
||||||
accMap = new HashMap();
|
accumulator[i] = new Long(accumulator[i].longValue() + valuel);
|
||||||
accumulator = new Long[accfields.length];
|
} catch (NumberFormatException e) {}
|
||||||
for (int i = 0; i < accfields.length; i++) {
|
}
|
||||||
accumulator[i] = new Long(0);
|
elementCount++;
|
||||||
}
|
}
|
||||||
}
|
} catch (IOException e) {}
|
||||||
|
|
||||||
// fill cluster and accumulator with values
|
// fill cluster
|
||||||
if ((sortfields != null) || (accfields != null)) try {
|
if (sortfields != null) for (int i = 0; i < sortfields.length; i++) sortClusterMap.put(sortfields[i], cluster[i]);
|
||||||
kelondroDyn.dynKeyIterator it = dyn.dynKeys(true, false);
|
|
||||||
String key, value;
|
// fill acc map
|
||||||
long valuel;
|
if (accfields != null) for (int i = 0; i < accfields.length; i++) accMap.put(accfields[i], accumulator[i]);
|
||||||
Map map;
|
}
|
||||||
while (it.hasNext()) {
|
|
||||||
key = (String) it.next();
|
public synchronized void set(String key, Map newMap) throws IOException {
|
||||||
map = get(key);
|
assert (key != null);
|
||||||
if (map == null) break;
|
assert (key.length() > 0);
|
||||||
|
assert (newMap != null);
|
||||||
if (sortfields != null) for (int i = 0; i < sortfields.length; i++) {
|
|
||||||
value = (String) map.get(sortfields[i]);
|
// update elementCount
|
||||||
if (value != null) cluster[i].setScore(key, kelondroMScoreCluster.string2score(value));
|
if ((sortfields != null) || (accfields != null)) {
|
||||||
}
|
final Map oldMap = getMap(key, false);
|
||||||
|
if (oldMap == null) {
|
||||||
if (accfields != null) for (int i = 0; i < accfields.length; i++) {
|
// new element
|
||||||
value = (String) map.get(accfields[i]);
|
elementCount++;
|
||||||
if (value != null) try {
|
} else {
|
||||||
valuel = Long.parseLong(value);
|
// element exists, update acc
|
||||||
accumulator[i] = new Long(accumulator[i].longValue() + valuel);
|
if (accfields != null) updateAcc(oldMap, false);
|
||||||
} catch (NumberFormatException e) {}
|
}
|
||||||
}
|
}
|
||||||
elementCount++;
|
|
||||||
}
|
super.set(key, new kelondroObjectsMapEntry(newMap));
|
||||||
} catch (IOException e) {}
|
|
||||||
|
// update sortCluster
|
||||||
// fill cluster
|
if (sortClusterMap != null) updateSortCluster(key, newMap);
|
||||||
if (sortfields != null) for (int i = 0; i < sortfields.length; i++) sortClusterMap.put(sortfields[i], cluster[i]);
|
|
||||||
|
// update accumulators with new values (add)
|
||||||
// fill acc map
|
if (accfields != null) updateAcc(newMap, true);
|
||||||
if (accfields != null) for (int i = 0; i < accfields.length; i++) accMap.put(accfields[i], accumulator[i]);
|
}
|
||||||
}
|
|
||||||
|
private void updateAcc(Map map, boolean add) {
|
||||||
public int keySize() {
|
String value;
|
||||||
return dyn.row().width(0);
|
long valuel;
|
||||||
}
|
Long accumulator;
|
||||||
|
for (int i = 0; i < accfields.length; i++) {
|
||||||
public int cacheNodeChunkSize() {
|
value = (String) map.get(accfields[i]);
|
||||||
return dyn.cacheNodeChunkSize();
|
if (value != null) {
|
||||||
}
|
try {
|
||||||
|
valuel = Long.parseLong(value);
|
||||||
public int cacheObjectChunkSize() {
|
accumulator = (Long) accMap.get(accfields[i]);
|
||||||
return dyn.cacheObjectChunkSize();
|
if (add) {
|
||||||
}
|
accMap.put(accfields[i], new Long(accumulator.longValue() + valuel));
|
||||||
|
} else {
|
||||||
public int[] cacheNodeStatus() {
|
accMap.put(accfields[i], new Long(accumulator.longValue() - valuel));
|
||||||
return dyn.cacheNodeStatus();
|
}
|
||||||
}
|
} catch (NumberFormatException e) {}
|
||||||
|
}
|
||||||
public long[] cacheObjectStatus() {
|
}
|
||||||
return dyn.cacheObjectStatus();
|
}
|
||||||
}
|
|
||||||
|
private void updateSortCluster(final String key, final Map map) {
|
||||||
public synchronized void set(String key, Map newMap) throws IOException {
|
String value;
|
||||||
assert (key != null);
|
kelondroMScoreCluster cluster;
|
||||||
assert (key.length() > 0);
|
for (int i = 0; i < sortfields.length; i++) {
|
||||||
assert (newMap != null);
|
value = (String) map.get(sortfields[i]);
|
||||||
// update elementCount
|
if (value != null) {
|
||||||
if ((sortfields != null) || (accfields != null)) {
|
cluster = (kelondroMScoreCluster) sortClusterMap.get(sortfields[i]);
|
||||||
final Map oldMap = get(key, false);
|
cluster.setScore(key, kelondroMScoreCluster.string2score(value));
|
||||||
if (oldMap == null) {
|
sortClusterMap.put(sortfields[i], cluster);
|
||||||
// new element
|
}
|
||||||
elementCount++;
|
}
|
||||||
} else {
|
}
|
||||||
// element exists, update acc
|
|
||||||
if (accfields != null) updateAcc(oldMap, false);
|
public synchronized void remove(String key) throws IOException {
|
||||||
}
|
if (key == null) return;
|
||||||
}
|
|
||||||
// write entry
|
// update elementCount
|
||||||
writeKra(key, newMap, "");
|
if ((sortfields != null) || (accfields != null)) {
|
||||||
|
final Map map = getMap(key);
|
||||||
// check for space in cache
|
if (map != null) {
|
||||||
checkCacheSpace();
|
// update count
|
||||||
|
elementCount--;
|
||||||
// write map to cache
|
|
||||||
cacheScore.setScore(key, (int) ((System.currentTimeMillis() - startup) / 1000));
|
// update accumulators (subtract)
|
||||||
cache.put(key, newMap);
|
if (accfields != null) updateAcc(map, false);
|
||||||
|
|
||||||
// update sortCluster
|
// remove from sortCluster
|
||||||
if (sortClusterMap != null) updateSortCluster(key, newMap);
|
if (sortfields != null) deleteSortCluster(key);
|
||||||
|
}
|
||||||
// update accumulators with new values (add)
|
}
|
||||||
if (accfields != null) updateAcc(newMap, true);
|
super.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void writeKra(final String key, final Map newMap, String comment) throws IOException {
|
public Map getMap(String key) {
|
||||||
// write map to kra
|
try {
|
||||||
final kelondroRA kra = dyn.getRA(key);
|
kelondroObjectsMapEntry mapEntry = (kelondroObjectsMapEntry) super.get(key);
|
||||||
kra.writeMap(newMap, comment);
|
if (mapEntry == null) return null;
|
||||||
kra.close();
|
return mapEntry.map();
|
||||||
}
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
private void updateAcc(Map map, boolean add) {
|
return null;
|
||||||
String value;
|
}
|
||||||
long valuel;
|
}
|
||||||
Long accumulator;
|
|
||||||
for (int i = 0; i < accfields.length; i++) {
|
protected Map getMap(String key, boolean cache) {
|
||||||
value = (String) map.get(accfields[i]);
|
try {
|
||||||
if (value != null) {
|
kelondroObjectsMapEntry mapEntry = (kelondroObjectsMapEntry) super.get(key, cache);
|
||||||
try {
|
if (mapEntry == null) return null;
|
||||||
valuel = Long.parseLong(value);
|
return mapEntry.map();
|
||||||
accumulator = (Long) accMap.get(accfields[i]);
|
} catch (IOException e) {
|
||||||
if (add) {
|
e.printStackTrace();
|
||||||
accMap.put(accfields[i], new Long(accumulator.longValue() + valuel));
|
return null;
|
||||||
} else {
|
}
|
||||||
accMap.put(accfields[i], new Long(accumulator.longValue() - valuel));
|
}
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {}
|
private void deleteSortCluster(final String key) {
|
||||||
}
|
if (key == null) return;
|
||||||
}
|
kelondroMScoreCluster cluster;
|
||||||
}
|
for (int i = 0; i < sortfields.length; i++) {
|
||||||
|
cluster = (kelondroMScoreCluster) sortClusterMap.get(sortfields[i]);
|
||||||
private void updateSortCluster(final String key, final Map map) {
|
cluster.deleteScore(key);
|
||||||
String value;
|
sortClusterMap.put(sortfields[i], cluster);
|
||||||
kelondroMScoreCluster cluster;
|
}
|
||||||
for (int i = 0; i < sortfields.length; i++) {
|
}
|
||||||
value = (String) map.get(sortfields[i]);
|
|
||||||
if (value != null) {
|
public synchronized Iterator keys(final boolean up, /* sorted by */ String field) {
|
||||||
cluster = (kelondroMScoreCluster) sortClusterMap.get(sortfields[i]);
|
// sorted iteration using the sortClusters
|
||||||
cluster.setScore(key, kelondroMScoreCluster.string2score(value));
|
if (sortClusterMap == null) return null;
|
||||||
sortClusterMap.put(sortfields[i], cluster);
|
final kelondroMScoreCluster cluster = (kelondroMScoreCluster) sortClusterMap.get(field);
|
||||||
}
|
if (cluster == null) return null; // sort field does not exist
|
||||||
}
|
//System.out.println("DEBUG: cluster for field " + field + ": " + cluster.toString());
|
||||||
}
|
return cluster.scores(up);
|
||||||
|
}
|
||||||
public synchronized void remove(String key) throws IOException {
|
|
||||||
// update elementCount
|
public synchronized mapIterator maps(final boolean up, final String field) {
|
||||||
if (key == null) return;
|
return new mapIterator(keys(up, field));
|
||||||
if ((sortfields != null) || (accfields != null)) {
|
}
|
||||||
final Map map = get(key);
|
|
||||||
if (map != null) {
|
public synchronized mapIterator maps(final boolean up, final boolean rotating) throws IOException {
|
||||||
// update count
|
return new mapIterator(keys(up, rotating));
|
||||||
elementCount--;
|
}
|
||||||
|
|
||||||
// update accumulators (subtract)
|
public synchronized mapIterator maps(final boolean up, final boolean rotating, final byte[] firstKey) throws IOException {
|
||||||
if (accfields != null) updateAcc(map, false);
|
return new mapIterator(keys(up, rotating, firstKey));
|
||||||
|
}
|
||||||
// remove from sortCluster
|
|
||||||
if (sortfields != null) deleteSortCluster(key);
|
public synchronized long getAcc(final String field) {
|
||||||
}
|
final Long accumulator = (Long) accMap.get(field);
|
||||||
}
|
if (accumulator == null) return -1;
|
||||||
// remove from cache
|
return accumulator.longValue();
|
||||||
cacheScore.deleteScore(key);
|
}
|
||||||
cache.remove(key);
|
|
||||||
|
public synchronized int size() {
|
||||||
// remove from file
|
if ((sortfields != null) || (accfields != null)) return elementCount;
|
||||||
dyn.remove(key);
|
return super.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteSortCluster(final String key) {
|
public void close() throws IOException {
|
||||||
if (key == null) return;
|
// close cluster
|
||||||
kelondroMScoreCluster cluster;
|
if (sortClusterMap != null) {
|
||||||
for (int i = 0; i < sortfields.length; i++) {
|
for (int i = 0; i < sortfields.length; i++) sortClusterMap.remove(sortfields[i]);
|
||||||
cluster = (kelondroMScoreCluster) sortClusterMap.get(sortfields[i]);
|
sortClusterMap = null;
|
||||||
cluster.deleteScore(key);
|
}
|
||||||
sortClusterMap.put(sortfields[i], cluster);
|
|
||||||
}
|
super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Map get(final String key) throws IOException {
|
public class mapIterator implements Iterator {
|
||||||
if (key == null) return null;
|
// enumerates Map-Type elements
|
||||||
return get(key, true);
|
// the key is also included in every map that is returned; it's key is 'key'
|
||||||
}
|
|
||||||
|
Iterator keyIterator;
|
||||||
private synchronized Map get(final String key, final boolean storeCache) throws IOException {
|
boolean finish;
|
||||||
// load map from cache
|
|
||||||
Map map = (Map) cache.get(key);
|
public mapIterator(Iterator keyIterator) {
|
||||||
if (map != null) return map;
|
this.keyIterator = keyIterator;
|
||||||
|
this.finish = false;
|
||||||
// load map from kra
|
}
|
||||||
if (!(dyn.existsDyn(key))) return null;
|
|
||||||
//final kelondroRA kra = new kelondroBufferedRA(dyn.getRA(key), dyn.cacheObjectChunkSize(), 0);
|
public boolean hasNext() {
|
||||||
final kelondroRA kra = dyn.getRA(key);
|
return (!(finish)) && (keyIterator != null) && (keyIterator.hasNext());
|
||||||
map = kra.readMap();
|
}
|
||||||
kra.close();
|
|
||||||
|
public Object next() {
|
||||||
if (storeCache) {
|
final String nextKey = (String) keyIterator.next();
|
||||||
// cache it also
|
if (nextKey == null) {
|
||||||
checkCacheSpace();
|
finish = true;
|
||||||
// write map to cache
|
return null;
|
||||||
cacheScore.setScore(key, (int) ((System.currentTimeMillis() - startup) / 1000));
|
}
|
||||||
cache.put(key, map);
|
final Map map = getMap(nextKey);
|
||||||
}
|
//assert (map != null) : "nextKey = " + nextKey;
|
||||||
|
if (map == null) throw new kelondroException("no more elements available");
|
||||||
// return value
|
map.put("key", nextKey);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void checkCacheSpace() {
|
public void remove() {
|
||||||
// check for space in cache
|
throw new UnsupportedOperationException();
|
||||||
if (cache.size() >= cachesize) {
|
}
|
||||||
// delete one entry
|
} // class mapIterator
|
||||||
final String delkey = (String) cacheScore.getMinObject();
|
}
|
||||||
cacheScore.deleteScore(delkey);
|
|
||||||
cache.remove(delkey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized kelondroDyn.dynKeyIterator keys(final boolean up, final boolean rotating) throws IOException {
|
|
||||||
// simple enumeration of key names without special ordering
|
|
||||||
return dyn.dynKeys(up, rotating);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized kelondroDyn.dynKeyIterator keys(final boolean up, final boolean rotating, final byte[] firstKey) throws IOException {
|
|
||||||
// simple enumeration of key names without special ordering
|
|
||||||
return dyn.dynKeys(up, rotating, firstKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized Iterator keys(final boolean up, /* sorted by */ String field) {
|
|
||||||
// sorted iteration using the sortClusters
|
|
||||||
if (sortClusterMap == null) return null;
|
|
||||||
final kelondroMScoreCluster cluster = (kelondroMScoreCluster) sortClusterMap.get(field);
|
|
||||||
if (cluster == null) return null; // sort field does not exist
|
|
||||||
//System.out.println("DEBUG: cluster for field " + field + ": " + cluster.toString());
|
|
||||||
return cluster.scores(up);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized mapIterator maps(final boolean up, final boolean rotating) throws IOException {
|
|
||||||
return new mapIterator(keys(up, rotating));
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized mapIterator maps(final boolean up, final boolean rotating, final byte[] firstKey) throws IOException {
|
|
||||||
return new mapIterator(keys(up, rotating, firstKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized mapIterator maps(final boolean up, final String field) {
|
|
||||||
return new mapIterator(keys(up, field));
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized long getAcc(final String field) {
|
|
||||||
final Long accumulator = (Long) accMap.get(field);
|
|
||||||
if (accumulator == null) return -1;
|
|
||||||
return accumulator.longValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized int size() {
|
|
||||||
if ((sortfields != null) || (accfields != null)) return elementCount;
|
|
||||||
try {
|
|
||||||
return dyn.sizeDyn();
|
|
||||||
} catch (IOException e) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() throws IOException {
|
|
||||||
// finish queue
|
|
||||||
//writeWorker.terminate(true);
|
|
||||||
|
|
||||||
// close cluster
|
|
||||||
if (sortClusterMap != null) {
|
|
||||||
for (int i = 0; i < sortfields.length; i++) sortClusterMap.remove(sortfields[i]);
|
|
||||||
sortClusterMap = null;
|
|
||||||
}
|
|
||||||
cache = null;
|
|
||||||
cacheScore = null;
|
|
||||||
|
|
||||||
// close file
|
|
||||||
dyn.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class mapIterator implements Iterator {
|
|
||||||
// enumerates Map-Type elements
|
|
||||||
// the key is also included in every map that is returned; it's key is 'key'
|
|
||||||
|
|
||||||
Iterator keyIterator;
|
|
||||||
boolean finish;
|
|
||||||
|
|
||||||
public mapIterator(Iterator keyIterator) {
|
|
||||||
this.keyIterator = keyIterator;
|
|
||||||
this.finish = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasNext() {
|
|
||||||
return (!(finish)) && (keyIterator.hasNext());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object next() {
|
|
||||||
final String nextKey = (String) keyIterator.next();
|
|
||||||
if (nextKey == null) {
|
|
||||||
finish = true;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
final Map map = get(nextKey);
|
|
||||||
//assert (map != null) : "nextKey = " + nextKey;
|
|
||||||
if (map == null) throw new kelondroException("no more elements available");
|
|
||||||
map.put("key", nextKey);
|
|
||||||
return map;
|
|
||||||
} catch (IOException e) {
|
|
||||||
finish = true;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
} // class mapIterator
|
|
||||||
|
|
||||||
} // class kelondroMap
|
|
@ -0,0 +1,215 @@
|
|||||||
|
// kelondroObjects.java
|
||||||
|
// -----------------------
|
||||||
|
// (C) 29.01.2007 by Michael Peter Christen; mc@anomic.de, Frankfurt a. M., Germany
|
||||||
|
// first published 2004 as kelondroMap on http://www.anomic.de
|
||||||
|
//
|
||||||
|
// This is a part of YaCy, a peer-to-peer based web search engine
|
||||||
|
//
|
||||||
|
// $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.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class kelondroObjects {
|
||||||
|
|
||||||
|
private kelondroDyn dyn;
|
||||||
|
private kelondroMScoreCluster cacheScore;
|
||||||
|
private HashMap cache;
|
||||||
|
private long startup;
|
||||||
|
private int cachesize;
|
||||||
|
|
||||||
|
|
||||||
|
public kelondroObjects(kelondroDyn dyn, int cachesize) {
|
||||||
|
this.dyn = dyn;
|
||||||
|
this.cache = new HashMap();
|
||||||
|
this.cacheScore = new kelondroMScoreCluster();
|
||||||
|
this.startup = System.currentTimeMillis();
|
||||||
|
this.cachesize = cachesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int keySize() {
|
||||||
|
return dyn.row().width(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int cacheNodeChunkSize() {
|
||||||
|
return dyn.cacheNodeChunkSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int cacheObjectChunkSize() {
|
||||||
|
return dyn.cacheObjectChunkSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] cacheNodeStatus() {
|
||||||
|
return dyn.cacheNodeStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long[] cacheObjectStatus() {
|
||||||
|
return dyn.cacheObjectStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void set(String key, kelondroObjectsEntry newMap) throws IOException {
|
||||||
|
assert (key != null);
|
||||||
|
assert (key.length() > 0);
|
||||||
|
assert (newMap != null);
|
||||||
|
|
||||||
|
// write entry
|
||||||
|
kelondroRA kra = dyn.getRA(key);
|
||||||
|
newMap.write(kra);
|
||||||
|
kra.close();
|
||||||
|
|
||||||
|
// check for space in cache
|
||||||
|
checkCacheSpace();
|
||||||
|
|
||||||
|
// write map to cache
|
||||||
|
cacheScore.setScore(key, (int) ((System.currentTimeMillis() - startup) / 1000));
|
||||||
|
cache.put(key, newMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void remove(String key) throws IOException {
|
||||||
|
// update elementCount
|
||||||
|
if (key == null) return;
|
||||||
|
|
||||||
|
// remove from cache
|
||||||
|
cacheScore.deleteScore(key);
|
||||||
|
cache.remove(key);
|
||||||
|
|
||||||
|
// remove from file
|
||||||
|
dyn.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized kelondroObjectsEntry get(final String key) throws IOException {
|
||||||
|
if (key == null) return null;
|
||||||
|
return get(key, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected synchronized kelondroObjectsEntry get(final String key, final boolean storeCache) throws IOException {
|
||||||
|
// load map from cache
|
||||||
|
kelondroObjectsEntry map = (kelondroObjectsEntry) cache.get(key);
|
||||||
|
if (map != null) return map;
|
||||||
|
|
||||||
|
// load map from kra
|
||||||
|
if (!(dyn.existsDyn(key))) return null;
|
||||||
|
|
||||||
|
// read object
|
||||||
|
kelondroRA kra = dyn.getRA(key);
|
||||||
|
map = new kelondroObjectsMapEntry(kra);
|
||||||
|
kra.close();
|
||||||
|
|
||||||
|
if (storeCache) {
|
||||||
|
// cache it also
|
||||||
|
checkCacheSpace();
|
||||||
|
// write map to cache
|
||||||
|
cacheScore.setScore(key, (int) ((System.currentTimeMillis() - startup) / 1000));
|
||||||
|
cache.put(key, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return value
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void checkCacheSpace() {
|
||||||
|
// check for space in cache
|
||||||
|
if (cache.size() >= cachesize) {
|
||||||
|
// delete one entry
|
||||||
|
final String delkey = (String) cacheScore.getMinObject();
|
||||||
|
cacheScore.deleteScore(delkey);
|
||||||
|
cache.remove(delkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized kelondroDyn.dynKeyIterator keys(final boolean up, final boolean rotating) throws IOException {
|
||||||
|
// simple enumeration of key names without special ordering
|
||||||
|
return dyn.dynKeys(up, rotating);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized kelondroDyn.dynKeyIterator keys(final boolean up, final boolean rotating, final byte[] firstKey) throws IOException {
|
||||||
|
// simple enumeration of key names without special ordering
|
||||||
|
return dyn.dynKeys(up, rotating, firstKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public synchronized objectIterator entries(final boolean up, final boolean rotating) throws IOException {
|
||||||
|
return new objectIterator(keys(up, rotating));
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized objectIterator entries(final boolean up, final boolean rotating, final byte[] firstKey) throws IOException {
|
||||||
|
return new objectIterator(keys(up, rotating, firstKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized int size() {
|
||||||
|
try {
|
||||||
|
return dyn.sizeDyn();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
// finish queue
|
||||||
|
//writeWorker.terminate(true);
|
||||||
|
|
||||||
|
cache = null;
|
||||||
|
cacheScore = null;
|
||||||
|
|
||||||
|
// close file
|
||||||
|
dyn.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class objectIterator implements Iterator {
|
||||||
|
// enumerates Map-Type elements
|
||||||
|
// the key is also included in every map that is returned; it's key is 'key'
|
||||||
|
|
||||||
|
Iterator keyIterator;
|
||||||
|
boolean finish;
|
||||||
|
|
||||||
|
public objectIterator(Iterator keyIterator) {
|
||||||
|
this.keyIterator = keyIterator;
|
||||||
|
this.finish = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
return (!(finish)) && (keyIterator.hasNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object next() {
|
||||||
|
final String nextKey = (String) keyIterator.next();
|
||||||
|
if (nextKey == null) {
|
||||||
|
finish = true;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final kelondroObjectsEntry obj = get(nextKey);
|
||||||
|
if (obj == null) throw new kelondroException("no more elements available");
|
||||||
|
return obj;
|
||||||
|
} catch (IOException e) {
|
||||||
|
finish = true;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
} // class mapIterator
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
// kelondroObjectsEntry.java
|
||||||
|
// -------------------------
|
||||||
|
// (C) 29.01.2007 by Michael Peter Christen; mc@anomic.de, Frankfurt a. M., Germany
|
||||||
|
// first published 2004 as part of kelondroMap on http://www.anomic.de
|
||||||
|
//
|
||||||
|
// This is a part of YaCy, a peer-to-peer based web search engine
|
||||||
|
//
|
||||||
|
// $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;
|
||||||
|
|
||||||
|
public interface kelondroObjectsEntry {
|
||||||
|
|
||||||
|
public void write(kelondroRA ra);
|
||||||
|
public void read(kelondroRA ra);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
// kelondroObjectsMapEntry.java
|
||||||
|
// ----------------------------
|
||||||
|
// (C) 29.01.2007 by Michael Peter Christen; mc@anomic.de, Frankfurt a. M., Germany
|
||||||
|
// first published 2004 as part of kelondroMap on http://www.anomic.de
|
||||||
|
//
|
||||||
|
// This is a part of YaCy, a peer-to-peer based web search engine
|
||||||
|
//
|
||||||
|
// $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.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class kelondroObjectsMapEntry implements kelondroObjectsEntry {
|
||||||
|
|
||||||
|
private Map entry;
|
||||||
|
|
||||||
|
public kelondroObjectsMapEntry() {
|
||||||
|
this.entry = new HashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public kelondroObjectsMapEntry(Map map) {
|
||||||
|
this.entry = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public kelondroObjectsMapEntry(kelondroRA ra) {
|
||||||
|
this.read(ra);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void read(kelondroRA ra) {
|
||||||
|
try {
|
||||||
|
this.entry = ra.readMap();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(kelondroRA ra) {
|
||||||
|
try {
|
||||||
|
ra.writeMap(this.entry, "");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map map() {
|
||||||
|
return this.entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue