yacy_search_server/source/de/anomic/yacy/yacyVersion.java
orbiter ce1adf9955 serialized all logging using concurrency:
high-performance search query situations as seen in yacy-metager integration showed deadlock situation caused by synchronization effects inside of sun.java code. It appears that the logger is not completely safe against deadlock situations in concurrent calls of the logger. One possible solution would be a outside-synchronization with 'synchronized' statements, but that would further apply blocking on all high-efficient methods that call the logger. It is much better to do a non-blocking hand-over of logging lines and work off log entries with a concurrent log writer. This also disconnects IO operations from logging, which can also cause IO operation when a log is written to a file. This commit not only moves the logger from kelondro to yacy.logging, it also inserts the concurrency methods to realize non-blocking logging.

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@6078 6c8d7289-2bf4-0310-a012-ef5d649a1542
2009-06-15 21:19:54 +00:00

206 lines
8.1 KiB
Java

package de.anomic.yacy;
import java.io.File;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.anomic.plasma.plasmaSwitchboard;
import de.anomic.yacy.logging.Log;
public class yacyVersion implements Comparator<yacyVersion>, Comparable<yacyVersion> {
public static final float YACY_SUPPORTS_PORT_FORWARDING = (float) 0.383;
public static final float YACY_SUPPORTS_GZIP_POST_REQUESTS_CHUNKED = (float) 0.58204761;
public static final float YACY_ACCEPTS_RANKING_TRANSMISSION = (float) 0.414;
public static final float YACY_HANDLES_COLLECTION_INDEX = (float) 0.486;
public static final float YACY_POVIDES_REMOTECRAWL_LISTS = (float) 0.550;
public static final float YACY_STANDARDREL_IS_PRO = (float) 0.557;
private static yacyVersion thisVersion = null;
/**
* information about latest release, retrieved by other peers release version,
* this value is overwritten when a peer with later version appears*/
public static double latestRelease = 0.1; //
private float releaseNr;
private String dateStamp;
private int svn;
private boolean mainRelease;
private String name;
/**
* parse a release file name
* <p>the have the following form:
* <ul>
* <li>yacy_dev_v${releaseVersion}_${DSTAMP}_${releaseNr}.tar.gz</li>
* <li>yacy_v${releaseVersion}_${DSTAMP}_${releaseNr}.tar.gz</li>
* </ul>
* i.e. yacy_v0.51_20070321_3501.tar.gz
* @param release
*/
public yacyVersion(String release) {
this.name = release;
if ((release == null) || (!((release.endsWith(".tar.gz") || (release.endsWith(".tar")))))) {
throw new RuntimeException("release file name '" + release + "' is not valid, no tar.gz");
}
// cut off tail
release = release.substring(0, release.length() - ((release.endsWith(".gz")) ? 7 : 4));
if (release.startsWith("yacy_pro_v")) {
release = release.substring(10);
} else if (release.startsWith("yacy_emb_v")) {
throw new RuntimeException("release file name '" + release + "' is not valid, no support for emb");
} else if (release.startsWith("yacy_v")) {
release = release.substring(6);
} else {
throw new RuntimeException("release file name '" + release + "' is not valid, wrong prefix");
}
// now all release names have the form
// ${releaseVersion}_${DSTAMP}_${releaseNr}
final String[] comp = release.split("_"); // should be 3 parts
if (comp.length != 3) {
throw new RuntimeException("release file name '" + release + "' is not valid, 3 information parts expected");
}
try {
this.releaseNr = Float.parseFloat(comp[0]);
} catch (final NumberFormatException e) {
throw new RuntimeException("release file name '" + release + "' is not valid, '" + comp[0] + "' should be a float number");
}
this.mainRelease = ((int) (this.getReleaseNr() * 100)) % 10 == 0;
//System.out.println("Release version " + this.releaseNr + " is " + ((this.mainRelease) ? "main" : "std"));
this.dateStamp = comp[1];
if (this.getDateStamp().length() != 8) {
throw new RuntimeException("release file name '" + release + "' is not valid, '" + comp[1] + "' should be a 8-digit date string");
}
try {
this.svn = Integer.parseInt(comp[2]);
} catch (final NumberFormatException e) {
throw new RuntimeException("release file name '" + release + "' is not valid, '" + comp[2] + "' should be a integer number");
}
// finished! we parsed a relase string
}
public static final yacyVersion thisVersion() {
// construct a virtual release name for this release
if (thisVersion == null) {
final plasmaSwitchboard sb = plasmaSwitchboard.getSwitchboard();
if (sb == null) return null;
final boolean full = new File(sb.getRootPath(), "libx").exists();
thisVersion = new yacyVersion(
"yacy" + ((full) ? "" : "_emb") +
"_v" + sb.getConfig("version", "0.1") + "_" +
sb.getConfig("vdate", "19700101") + "_" +
sb.getConfig("svnRevision", "0") + ".tar.gz");
}
return thisVersion;
}
/**
* returns 0 if this object is equal to the obj, -1 if this is smaller
* than obj and 1 if this is greater than obj
*/
public int compareTo(final yacyVersion obj) {
return compare(this, obj);
}
/**
* compare-operator for two yacyVersion objects
* must be implemented to make it possible to put this object into
* a ordered structure, like TreeSet or TreeMap
*/
public int compare(final yacyVersion v0, final yacyVersion v1) {
return (Integer.valueOf(v0.getSvn())).compareTo(Integer.valueOf(v1.getSvn()));
}
public boolean equals(final Object obj) {
if(obj instanceof yacyVersion) {
final yacyVersion v = (yacyVersion) obj;
return (this.getSvn() == v.getSvn()) && (this.getName().equals(v.getName()));
}
return false;
}
public int hashCode() {
return this.getName().hashCode();
}
/**
* Converts combined version-string to a pretty string, e.g. "0.435/01818" or "dev/01818" (development version) or "dev/00000" (in case of wrong input)
*
* @param ver Combined version string matching regular expression: "\A(\d+\.\d{3})(\d{4}|\d{5})\z" <br>
* (i.e.: start of input, 1 or more digits in front of decimal point, decimal point followed by 3 digits as major version, 4 or 5 digits for SVN-Version, end of input)
* @return If the major version is &lt; 0.11 - major version is separated from SVN-version by '/', e.g. "0.435/01818" <br>
* If the major version is &gt;= 0.11 - major version is replaced by "dev" and separated SVN-version by '/', e.g."dev/01818" <br>
* "dev/00000" - If the input does not matcht the regular expression above
*/
public static String combined2prettyVersion(final String ver) {
return combined2prettyVersion(ver, "");
}
public static String combined2prettyVersion(final String ver, final String computerName) {
final Matcher matcher = Pattern.compile("\\A(\\d+\\.\\d{1,3})(\\d{0,5})\\z").matcher(ver);
if (!matcher.find()) {
Log.logWarning("STARTUP", "Peer '"+computerName+"': wrong format of version-string: '" + ver + "'. Using default string 'dev/00000' instead");
return "dev/00000";
}
final String mainversion = (Double.parseDouble(matcher.group(1)) < 0.11 ? "dev" : matcher.group(1));
String revision = matcher.group(2);
for(int i=revision.length();i<5;++i) revision += "0";
return mainversion+"/"+revision;
}
/**
* Combines the version of YaCy with the versionnumber from SVN to a
* combined version
*
* @param version Current given version.
* @param svn Current version given from SVN.
* @return String with the combined version.
*/
public static double versvn2combinedVersion(final double version, final int svn) {
return (Math.rint((version*100000000.0) + (svn))/100000000);
}
/**
* Timestamp of this version
* @return timestamp
*/
public String getDateStamp() {
return dateStamp;
}
/**
* SVN revision of release
* @return svn revision as integer
*/
public int getSvn() {
return svn;
}
/**
* Whether this is a stable main release or not
* @return
*/
public boolean isMainRelease() {
return mainRelease;
}
/**
* release number as float (e. g. 7.04)
* @return
*/
public float getReleaseNr() {
return releaseNr;
}
public String getName() {
return name;
}
}