From e374aca2cddc1606b5f4cdc5e179f82f8fca2011 Mon Sep 17 00:00:00 2001 From: orbiter Date: Tue, 12 Apr 2005 15:45:50 +0000 Subject: [PATCH] enhanced exception handling in kelondro git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@14 6c8d7289-2bf4-0310-a012-ef5d649a1542 --- source/de/anomic/kelondro/kelondroDyn.java | 2 +- .../de/anomic/kelondro/kelondroException.java | 55 +++++++++++++ source/de/anomic/kelondro/kelondroMap.java | 2 +- .../de/anomic/kelondro/kelondroRecords.java | 26 +++--- source/de/anomic/kelondro/kelondroTree.java | 22 ++--- .../plasma/plasmaWordIndexFileCache.java | 12 ++- source/de/anomic/yacy/yacySeedDB.java | 80 ++++++++++++------- 7 files changed, 143 insertions(+), 56 deletions(-) create mode 100644 source/de/anomic/kelondro/kelondroException.java diff --git a/source/de/anomic/kelondro/kelondroDyn.java b/source/de/anomic/kelondro/kelondroDyn.java index 6102a5fdc..c5c1acff5 100644 --- a/source/de/anomic/kelondro/kelondroDyn.java +++ b/source/de/anomic/kelondro/kelondroDyn.java @@ -161,7 +161,7 @@ public class kelondroDyn extends kelondroTree { byte[][] nt; while (ri.hasNext()) { nt = (byte[][]) ri.next(); - if (nt == null) return null; + if (nt == null) throw new kelondroException(filename, "no more elements available"); g = nt[0]; if (g == null) return null; k = new String(g, 0, keylen); diff --git a/source/de/anomic/kelondro/kelondroException.java b/source/de/anomic/kelondro/kelondroException.java new file mode 100644 index 000000000..57a617355 --- /dev/null +++ b/source/de/anomic/kelondro/kelondroException.java @@ -0,0 +1,55 @@ +// kelondroException.java +// ----------------------- +// part of The Kelondro Database +// (C) by Michael Peter Christen; mc@anomic.de +// first published on http://www.anomic.de +// Frankfurt, Germany, 2005 +// last major change: 12.04.2005 +// +// 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 +// +// Using this software in any meaning (reading, learning, copying, compiling, +// 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 +// 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 +// software may allow other people or application to access your computer and +// any attached devices and is highly dependent on the configuration of the +// software which must be done by the user of the software; the author(s) is +// (are) also not responsible for proper configuration and usage of the +// software, even if provoked by documentation provided together with +// the software. +// +// Any changes to this file according to the GPL as documented in the file +// gpl.txt aside this file in the shipment you received can be done to the +// lines that follows this copyright notice here, but changes must not be +// done inside the copyright notive above. A re-distribution must contain +// the intact and unchanged copyright notice. +// Contributions and changes to the program code must be marked as such. + +package de.anomic.kelondro; + +public class kelondroException extends java.lang.RuntimeException { + + + public kelondroException() { + super("unspecific-error"); + } + + public kelondroException(String database, String message) { + super(message + " in database '" + database + "'"); + } + +} diff --git a/source/de/anomic/kelondro/kelondroMap.java b/source/de/anomic/kelondro/kelondroMap.java index 7044b1677..1cb2c215d 100644 --- a/source/de/anomic/kelondro/kelondroMap.java +++ b/source/de/anomic/kelondro/kelondroMap.java @@ -423,7 +423,7 @@ public class kelondroMap { } try { Map map = get(nextKey); - if (map == null) return null; + if (map == null) throw new kelondroException(dyn.filename, "no more elements available"); map.put("key", nextKey); return map; } catch (IOException e) { diff --git a/source/de/anomic/kelondro/kelondroRecords.java b/source/de/anomic/kelondro/kelondroRecords.java index 30d9955cd..8e50bc7d5 100644 --- a/source/de/anomic/kelondro/kelondroRecords.java +++ b/source/de/anomic/kelondro/kelondroRecords.java @@ -100,7 +100,7 @@ public class kelondroRecords { // POS_NODES : (USEDC + FREEC) * (overhead + sum(all: COLWIDTHS)) : Node Objects // values that are only present at run-time - private String filename; // the database's file name + protected String filename; // the database's file name protected kelondroRA entryFile; // the database file private int overhead; // OHBYTEC + 4 * OHHANDLEC = size of additional control bytes private int recordsize; // (overhead + sum(all: COLWIDTHS)) = the overall size of a record @@ -429,15 +429,15 @@ public class kelondroRecords { // the parentNode can be given if an auto-fix in the following case is wanted if (handle.index > USEDC + FREEC) { if (parentNode == null) { - throw new IllegalArgumentException("INTERNAL ERROR: node handle index exceeds size. No auto-fix node was submitted. This is a serious failure."); + throw new kelondroException(filename, "INTERNAL ERROR: node handle index exceeds size. No auto-fix node was submitted. This is a serious failure."); } else { try { Handle[] handles = parentNode.getOHHandle(); handles[referenceInParent] = null; parentNode.setOHHandle(handles); - throw new IllegalArgumentException("INTERNAL ERROR: node handle index exceeds size. The bad node has been auto-fixed"); + throw new kelondroException(filename, "INTERNAL ERROR: node handle index exceeds size. The bad node has been auto-fixed"); } catch (IOException ee) { - throw new IllegalArgumentException("INTERNAL ERROR: node handle index exceeds size. It was tried to fix the bad node, but failed with an IOException: " + ee.getMessage()); + throw new kelondroException(filename, "INTERNAL ERROR: node handle index exceeds size. It was tried to fix the bad node, but failed with an IOException: " + ee.getMessage()); } } } @@ -451,13 +451,13 @@ public class kelondroRecords { } protected Handle handle() { // if this entry has an index, return it - if (this.handle.index == NUL) throw new IllegalStateException("the entry has no index assigned"); + if (this.handle.index == NUL) throw new kelondroException(filename, "the entry has no index assigned"); return new Handle(this.handle.index); } protected synchronized void setOHByte(byte[] b) throws IOException { if (b == null) throw new IllegalArgumentException("setOHByte: setting null value does not make any sense"); if (b.length != OHBYTEC) throw new IllegalArgumentException("setOHByte: wrong array size"); - if (this.handle.index == NUL) throw new IllegalStateException("setOHByte: no handle assigned"); + if (this.handle.index == NUL) throw new kelondroException(filename, "setOHByte: no handle assigned"); if (this.ohBytes == null) this.ohBytes = new byte[OHBYTEC]; entryFile.seek(seekpos(this.handle)); for (int j = 0; j < ohBytes.length; j++) { @@ -469,7 +469,7 @@ public class kelondroRecords { protected synchronized void setOHHandle(Handle[] i) throws IOException { if (i == null) throw new IllegalArgumentException("setOHint: setting null value does not make any sense"); if (i.length != OHHANDLEC) throw new IllegalArgumentException("setOHHandle: wrong array size"); - if (this.handle.index == NUL) throw new IllegalStateException("setOHHandle: no handle assigned"); + if (this.handle.index == NUL) throw new kelondroException(filename, "setOHHandle: no handle assigned"); if (this.ohHandle == null) this.ohHandle = new Handle[OHHANDLEC]; entryFile.seek(seekpos(this.handle) + OHBYTEC); for (int j = 0; j < ohHandle.length; j++) { @@ -483,7 +483,7 @@ public class kelondroRecords { } protected synchronized byte[] getOHByte() throws IOException { if (ohBytes == null) { - if (this.handle.index == NUL) throw new IllegalStateException("Cannot load OH values"); + if (this.handle.index == NUL) throw new kelondroException(filename, "Cannot load OH values"); ohBytes = new byte[OHBYTEC]; entryFile.seek(seekpos(this.handle)); for (int j = 0; j < ohBytes.length; j++) { @@ -495,7 +495,7 @@ public class kelondroRecords { } protected synchronized Handle[] getOHHandle() throws IOException { if (ohHandle == null) { - if (this.handle.index == NUL) throw new IllegalStateException("Cannot load OH values"); + if (this.handle.index == NUL) throw new kelondroException(filename, "Cannot load OH values"); ohHandle = new Handle[OHHANDLEC]; entryFile.seek(seekpos(this.handle) + OHBYTEC); int i; @@ -539,7 +539,7 @@ public class kelondroRecords { if ((values == null) || (values[0] == null)) { // load from database, but ONLY the key! if (this.handle.index == NUL) { - throw new IllegalStateException("Cannot load Key"); + throw new kelondroException(filename, "Cannot load Key"); } else { values = new byte[COLWIDTHS.length][]; entryFile.seek(seekpos(this.handle) + overhead); @@ -558,7 +558,7 @@ public class kelondroRecords { if ((values == null) || (values[0] == null)) { // load ALL values from database if (this.handle.index == NUL) { - throw new IllegalStateException("Cannot load values"); + throw new kelondroException(filename, "Cannot load values"); } else { values = new byte[COLWIDTHS.length][]; long seek = seekpos(this.handle) + overhead; @@ -592,7 +592,7 @@ public class kelondroRecords { // then writing to the file is done here // can only be called if the index has not been defined yet if (this.handle.index != NUL) { - throw new IllegalStateException("double assignement of handles"); + throw new kelondroException(filename, "double assignement of handles"); } // create new index by expanding the file at the end // or by recycling used records @@ -600,7 +600,7 @@ public class kelondroRecords { // place the data to the file if ((values == null) || ((values != null) && (values.length > 1) && (values[1] == null))) { // there is nothing to save - throw new IllegalStateException("no values to save"); + throw new kelondroException(filename, "no values to save"); } entryFile.seek(seekpos(this.handle)); if (ohBytes == null) {for (int i = 0; i < OHBYTEC; i++) entryFile.writeByte(0);} diff --git a/source/de/anomic/kelondro/kelondroTree.java b/source/de/anomic/kelondro/kelondroTree.java index fcf6f60c3..1144e789a 100644 --- a/source/de/anomic/kelondro/kelondroTree.java +++ b/source/de/anomic/kelondro/kelondroTree.java @@ -279,9 +279,9 @@ public class kelondroTree extends kelondroRecords implements Comparator { // go to next node searchHandle = searchNode.getOHHandle()[ct]; - if (searchHandle == null) throw new IllegalArgumentException("start node does not exist (handle null)"); + if (searchHandle == null) throw new kelondroException(filename, "start node does not exist (handle null)"); searchNode = getNode(searchHandle, searchNode, ct); - if (searchNode == null) throw new IllegalArgumentException("start node does not exist (node null)"); + if (searchNode == null) throw new kelondroException(filename, "start node does not exist (node null)"); } // now every parent node to the start node is on the stack } @@ -292,8 +292,8 @@ public class kelondroTree extends kelondroRecords implements Comparator { public Object next() { count++; - if (nextNode == null) return null; - if (count > size()) return null; + if (nextNode == null) throw new kelondroException(filename, "no more entries available"); + if (count > size()) throw new kelondroException(filename, "internal loopback; database corrupted"); Object ret = nextNode; // middle-case @@ -390,7 +390,7 @@ public class kelondroTree extends kelondroRecords implements Comparator { // a node with this key does not exist and there is no node at all // this therefore creates the root node if an only if there was no root Node yet if (getHandle(root) != null) - throw new IllegalArgumentException("tried to create root node twice"); + throw new kelondroException(filename, "tried to create root node twice"); // we dont have any Nodes in the file, so start here to create one Node e = newNode(newrow); e.save(); @@ -420,13 +420,13 @@ public class kelondroTree extends kelondroRecords implements Comparator { // check consistency and link new node to parent node parentOHHandle = parentNode.getOHHandle(); // {parent, leftchild, rightchild} if (searchResult.isLeft()) { - if (parentOHHandle[leftchild] != null) throw new IllegalArgumentException("tried to create leftchild node twice"); + if (parentOHHandle[leftchild] != null) throw new kelondroException(filename, "tried to create leftchild node twice"); parentOHHandle[leftchild] = theNode.handle(); } else if (searchResult.isRight()) { - if (parentOHHandle[rightchild] != null) throw new IllegalArgumentException("tried to create rightchild node twice"); + if (parentOHHandle[rightchild] != null) throw new kelondroException(filename, "tried to create rightchild node twice"); parentOHHandle[rightchild] = theNode.handle(); } else { - throw new IllegalArgumentException("neither left nor right child"); + throw new kelondroException(filename, "neither left nor right child"); } parentNode.setOHHandle(parentOHHandle); @@ -895,10 +895,10 @@ public class kelondroTree extends kelondroRecords implements Comparator { public Object next() { try { Node nextNode = (Node) nodeIterator.next(); - if (nextNode == null) return null; // this is an error case of the nodeIterator + if (nextNode == null) throw new kelondroException(filename, "no more elements available"); return nextNode.getValues(); } catch (IOException e) { - return null; + throw new kelondroException(filename, "io-error: " + e.getMessage()); } } @@ -1170,7 +1170,7 @@ public class kelondroTree extends kelondroRecords implements Comparator { return compare(((Node) a).getKey(), ((Node) b).getKey()); } else throw new IllegalArgumentException("Object type or Object type combination not supported"); } catch (IOException e) { - throw new IllegalStateException("IOException: " + e.getMessage()); + throw new kelondroException(filename, "IOException: " + e.getMessage()); } } diff --git a/source/de/anomic/plasma/plasmaWordIndexFileCache.java b/source/de/anomic/plasma/plasmaWordIndexFileCache.java index c90e43bfe..517686efb 100644 --- a/source/de/anomic/plasma/plasmaWordIndexFileCache.java +++ b/source/de/anomic/plasma/plasmaWordIndexFileCache.java @@ -117,7 +117,13 @@ public class plasmaWordIndexFileCache { protected Iterator wordHashes(String wordHash, boolean up) throws IOException { - return indexCache.rows(up, false, (wordHash == null) ? null : wordHash.getBytes()); + try { + return indexCache.rows(up, false, (wordHash == null) ? null : wordHash.getBytes()); + } catch (kelondroException e) { + de.anomic.server.serverLog.logError("PLASMA", "kelondro error in plasmaWordIndexFileCache: " + e.getMessage() + "; deleting index for " + wordHash); + deleteComplete(wordHash); + return new HashSet().iterator(); + } } protected plasmaWordIndexEntity getIndex(String wordHash, boolean deleteIfEmpty) throws IOException { @@ -154,10 +160,10 @@ public class plasmaWordIndexFileCache { row[1][0] = (byte) entries; try { indexCache.put(row); - } catch (IllegalArgumentException e) { + } catch (kelondroException e) { // this is a very bad case; a database inconsistency occurred deleteComplete(wordHash); - System.out.println("fatal error in plasmaWordIndexFileCacle.addEntriesToIndex: write to word hash file " + wordHash + " failed - " + e.getMessage()); + System.out.println("fatal error in plasmaWordIndexFileCacle.addEntriesToIndex: write to word hash file " + wordHash + " failed - " + e.getMessage() + " - index deleted."); } } // finished! diff --git a/source/de/anomic/yacy/yacySeedDB.java b/source/de/anomic/yacy/yacySeedDB.java index 45ba56063..b6fc27ba5 100644 --- a/source/de/anomic/yacy/yacySeedDB.java +++ b/source/de/anomic/yacy/yacySeedDB.java @@ -256,21 +256,21 @@ public class yacySeedDB { int searchcount = 1000; if (searchcount > sizeConnected()) searchcount = sizeConnected(); try { - while ((s.hasMoreElements()) && (searchcount-- > 0)) { - ys = (yacySeed) s.nextElement(); - if ((ys != null) && ((t = ys.get("LastSeen", "")).length() > 10)) try { - absage = Math.abs(yacyCore.universalTime() - yacyCore.shortFormatter.parse(t).getTime()); - seedScore.addScore(ys.hash, (int) absage); - } catch (Exception e) {} - } - - // result is now in the score object; create a result vector - yacySeed[] result = new yacySeed[count]; - Iterator it = seedScore.scores(up); - int c = 0; - while ((c < count) && (it.hasNext())) result[c++] = getConnected((String) it.next()); - return result; - } catch (NullPointerException e) { + while ((s.hasMoreElements()) && (searchcount-- > 0)) { + ys = (yacySeed) s.nextElement(); + if ((ys != null) && ((t = ys.get("LastSeen", "")).length() > 10)) try { + absage = Math.abs(yacyCore.universalTime() - yacyCore.shortFormatter.parse(t).getTime()); + seedScore.addScore(ys.hash, (int) absage); + } catch (Exception e) {} + } + + // result is now in the score object; create a result vector + yacySeed[] result = new yacySeed[count]; + Iterator it = seedScore.scores(up); + int c = 0; + while ((c < count) && (it.hasNext())) result[c++] = getConnected((String) it.next()); + return result; + } catch (kelondroException e) { seedActiveDB = resetSeedTable(seedActiveDB, seedActiveDBFile); System.out.println("Internal Error at yacySeedDB.seedsByAge: " + e.getMessage()); e.printStackTrace(); @@ -320,9 +320,16 @@ public class yacySeedDB { seedActiveDB.set(seed.hash, seed.getMap()); seedPassiveDB.remove(seed.hash); seedPotentialDB.remove(seed.hash); - } catch (IOException e) { - } catch (IllegalArgumentException e) { - System.out.println("ERROR add: seed.db corrupt; resetting seed.db"); + } catch (IOException e){ + System.out.println("ERROR add: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); + e.printStackTrace(); + seedActiveDB = resetSeedTable(seedActiveDB, seedActiveDBFile); + } catch (kelondroException e){ + System.out.println("ERROR add: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); + e.printStackTrace(); + seedActiveDB = resetSeedTable(seedActiveDB, seedActiveDBFile); + } catch (IllegalArgumentException e) { + System.out.println("ERROR add: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); e.printStackTrace(); seedActiveDB = resetSeedTable(seedActiveDB, seedActiveDBFile); } @@ -337,8 +344,15 @@ public class yacySeedDB { seedActiveDB.remove(seed.hash); seedPotentialDB.remove(seed.hash); } catch (IOException e) { - } catch (IllegalArgumentException e) { - System.out.println("ERROR add: seed.db corrupt; resetting seed.db"); + System.out.println("ERROR add: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); + e.printStackTrace(); + seedPassiveDB = resetSeedTable(seedPassiveDB, seedPassiveDBFile); + } catch (kelondroException e) { + System.out.println("ERROR add: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); + e.printStackTrace(); + seedPassiveDB = resetSeedTable(seedPassiveDB, seedPassiveDBFile); + } catch (IllegalArgumentException e) { + System.out.println("ERROR add: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); e.printStackTrace(); seedPassiveDB = resetSeedTable(seedPassiveDB, seedPassiveDBFile); } @@ -353,8 +367,15 @@ public class yacySeedDB { seedActiveDB.remove(seed.hash); seedPassiveDB.remove(seed.hash); } catch (IOException e) { + System.out.println("ERROR add: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); + e.printStackTrace(); + seedPassiveDB = resetSeedTable(seedPassiveDB, seedPassiveDBFile); + } catch (kelondroException e) { + System.out.println("ERROR add: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); + e.printStackTrace(); + seedPassiveDB = resetSeedTable(seedPassiveDB, seedPassiveDBFile); } catch (IllegalArgumentException e) { - System.out.println("ERROR add: seed.db corrupt; resetting seed.db"); + System.out.println("ERROR add: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); e.printStackTrace(); seedPassiveDB = resetSeedTable(seedPassiveDB, seedPassiveDBFile); } @@ -567,8 +588,14 @@ public class yacySeedDB { try { it = (firstKey == null) ? database.maps(up, rot) : database.maps(up, rot, firstKey); nextSeed = internalNext(); - } catch (Exception e) { - System.out.println("ERROR seedLinEnum: seed.db corrupt; resetting seed.db"); + } catch (IOException e) { + System.out.println("ERROR seedLinEnum: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); + e.printStackTrace(); + if (database == seedActiveDB) seedActiveDB = resetSeedTable(seedActiveDB, seedActiveDBFile); + if (database == seedPassiveDB) seedPassiveDB = resetSeedTable(seedPassiveDB, seedPassiveDBFile); + it = null; + } catch (kelondroException e) { + System.out.println("ERROR seedLinEnum: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); e.printStackTrace(); if (database == seedActiveDB) seedActiveDB = resetSeedTable(seedActiveDB, seedActiveDBFile); if (database == seedPassiveDB) seedPassiveDB = resetSeedTable(seedPassiveDB, seedPassiveDBFile); @@ -581,14 +608,13 @@ public class yacySeedDB { try { it = database.maps(up, field); nextSeed = internalNext(); - } catch (Exception e) { - System.out.println("ERROR seedLinEnum: seed.db corrupt; resetting seed.db"); + } catch (kelondroException e) { + System.out.println("ERROR seedLinEnum: seed.db corrupt (" + e.getMessage() + "); resetting seed.db"); e.printStackTrace(); if (database == seedActiveDB) seedActiveDB = resetSeedTable(seedActiveDB, seedActiveDBFile); if (database == seedPassiveDB) seedPassiveDB = resetSeedTable(seedPassiveDB, seedPassiveDBFile); it = null; - } - } + } } public boolean hasMoreElements() { return (nextSeed != null);