experimental visualization of DHT access during global search (temporary)

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@977 6c8d7289-2bf4-0310-a012-ef5d649a1542
pull/1/head
orbiter 19 years ago
parent 4dcbc26ef1
commit 097009d910

@ -44,25 +44,18 @@
// Contributions and changes to the program code must be marked as such.
import java.awt.image.BufferedImage;
import java.util.Enumeration;
import java.util.Date;
import java.awt.image.BufferedImage;
import de.anomic.http.httpHeader;
import de.anomic.server.serverObjects;
import de.anomic.server.serverSwitch;
import de.anomic.tools.ImagePainter;
import de.anomic.yacy.yacyCore;
import de.anomic.yacy.yacySeed;
import de.anomic.plasma.plasmaGrafics;
// draw a picture of the yacy network
public class NetworkPicture {
private static int shortestName = 10;
private static int longestName = 12;
public static BufferedImage respond(httpHeader header, serverObjects post, serverSwitch env) {
int width = 640;
@ -79,133 +72,7 @@ public class NetworkPicture {
maxCount = post.getInt("max", 1000);
}
int innerradius = Math.min(width, height) / 5;
int outerradius = innerradius + innerradius * yacyCore.seedDB.sizeConnected() / 100;
if (outerradius > innerradius * 2) outerradius = innerradius * 2;
shortestName = 10;
longestName = 12;
ImagePainter img = new ImagePainter(width, height, "000010");
img.setMode(ImagePainter.MODE_ADD);
if (yacyCore.seedDB == null) return img.toImage(true); // no other peers known
int size = yacyCore.seedDB.sizeConnected();
if (size == 0) return img.toImage(true); // no other peers known
// draw network circle
img.setColor("008020");
img.arc(width / 2, height / 2, innerradius - 20, innerradius + 20, 0, 360);
//System.out.println("Seed Maximum distance is " + yacySeed.maxDHTDistance);
//System.out.println("Seed Minimum distance is " + yacySeed.minDHTNumber);
yacySeed seed;
int angle;
long lastseen;
// draw connected senior and principals
int count = 0;
int totalCount = 0;
Enumeration e = yacyCore.seedDB.seedsConnected(true, false, null);
while (e.hasMoreElements() && count < maxCount) {
seed = (yacySeed) e.nextElement();
if (seed != null) {
drawPeer(img, width / 2, height / 2, innerradius, outerradius, seed, "000040", "608860", "B0FFB0");
count++;
}
}
totalCount += count;
// draw disconnected senior and principals that have been seen lately
count = 0;
e = yacyCore.seedDB.seedsSortedDisconnected(true, yacySeed.LASTSEEN);
while (e.hasMoreElements() && count < maxCount) {
seed = (yacySeed) e.nextElement();
if (seed != null) {
lastseen = Math.abs((System.currentTimeMillis() - seed.getLastSeenTime()) / 1000 / 60);
if (lastseen > passiveLimit) break; // we have enough, this list is sorted so we don't miss anything
drawPeer(img, width / 2, height / 2, innerradius, outerradius, seed, "101010", "401000", "802000");
count++;
}
}
totalCount += count;
// draw juniors that have been seen lately
count = 0;
e = yacyCore.seedDB.seedsSortedPotential(true, yacySeed.LASTSEEN);
while (e.hasMoreElements() && count < maxCount) {
seed = (yacySeed) e.nextElement();
if (seed != null) {
lastseen = Math.abs((System.currentTimeMillis() - seed.getLastSeenTime()) / 1000 / 60);
if (lastseen > potentialLimit) break; // we have enough, this list is sorted so we don't miss anything
drawPeer(img, width / 2, height / 2, innerradius, outerradius, seed, "202000", "505000", "A0A000");
count++;
}
}
totalCount += count;
// draw my own peer
drawPeer(img, width / 2, height / 2, innerradius, outerradius, yacyCore.seedDB.mySeed, "800000", "AAAAAA", "FFFFFF");
// draw description
img.setColor("FFFFFF");
img.setMode(ImagePainter.MODE_ADD);
img.print(2, 8, "THE YACY NETWORK", true);
img.print(2, 16, "DRAWING OF " + totalCount + " SELECTED PEERS", true);
img.print(width - 2, 8, "SNAPSHOT FROM " + new Date().toString().toUpperCase(), false);
return img.toImage(true);
}
private static void drawPeer(ImagePainter img, int x, int y, int innerradius, int outerradius, yacySeed seed, String colorDot, String colorLine, String colorText) {
String name = seed.getName().toUpperCase();
if (name.length() < shortestName) shortestName = name.length();
if (name.length() > longestName) longestName = name.length();
int angle = (int) ((long) 360 * (seed.dhtDistance() / (yacySeed.maxDHTDistance / (long) 10000)) / (long) 10000);
//System.out.println("Seed " + seed.hash + " has distance " + seed.dhtDistance() + ", angle = " + angle);
int linelength = 20 + outerradius * (20 * (name.length() - shortestName) / (longestName - shortestName) + (Math.abs(seed.hash.hashCode()) % 20)) / 60;
if (linelength > outerradius) linelength = outerradius;
int dotsize = 6 + 2 * (int) (seed.getLinkCount() / 500000L);
if (dotsize > 18) dotsize = 18;
img.setMode(ImagePainter.MODE_ADD);
// draw dot
img.setColor(colorDot);
img.arcDot(x, y, innerradius, angle, dotsize);
// draw line to text
img.setColor(colorLine);
img.arcLine(x, y, innerradius + 18, innerradius + linelength, angle);
// draw text
img.setColor(colorText);
img.arcPrint(x, y, innerradius + linelength, angle, name);
// draw corona around dot for crawling activity
int ppm10 = seed.getPPM() / 10;
if (ppm10 > 0) {
if (ppm10 > 3) ppm10 = 3;
// draw a wave around crawling peers
long strength;
img.setMode(ImagePainter.MODE_SUB);
img.setColor("303030");
img.arcArc(x, y, innerradius, angle, dotsize + 1, dotsize + 1, 0, 360);
int waveradius = innerradius / 2;
for (int r = 0; r < waveradius; r++) {
strength = (waveradius - r) * (long) (0x08 * ppm10 * (1.0 + Math.sin(Math.PI * 16 * r / waveradius))) / waveradius;
//System.out.println("r = " + r + ", Strength = " + strength);
img.setColor((strength << 16) | (strength << 8) | strength);
img.arcArc(x, y, innerradius, angle, dotsize + r, dotsize + r, 0, 360);
}
/*
// draw corona
img.setMode(ImagePainter.MODE_SUB);
img.setColor("303030");
img.arcArc(x, y, innerradius, angle, dotsize + 1, dotsize + ppm10 + 1, 0, 360);
img.setMode(ImagePainter.MODE_ADD);
img.setColor("200000");
img.arcArc(x, y, innerradius, angle, dotsize + ppm10 , dotsize + ppm10 , 0, 360);
img.setColor("500000");
img.arcArc(x, y, innerradius, angle, dotsize + ppm10 + 1, dotsize + ppm10 + 1, 0, 360);
*/
}
return plasmaGrafics.getNetworkPicture(10000, width, height, passiveLimit, potentialLimit, maxCount).toImage(true);
}
}

@ -0,0 +1,68 @@
// SearchEventPicture.java
// -----------------------
// part of YaCy
// (C) by Michael Peter Christen; mc@anomic.de
// first published on http://www.anomic.de
// Frankfurt, Germany, 2005
// Created 24.10.2005
//
// $LastChangedDate: 2005-10-23 19:50:27 +0200 (Sun, 23 Oct 2005) $
// $LastChangedRevision: 976 $
// $LastChangedBy: orbiter $
//
// 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.
import java.awt.image.BufferedImage;
import de.anomic.http.httpHeader;
import de.anomic.server.serverObjects;
import de.anomic.server.serverSwitch;
import de.anomic.plasma.plasmaGrafics;
import de.anomic.tools.ImagePainter;
// draw a picture of the yacy network
public class SearchEventPicture {
public static BufferedImage respond(httpHeader header, serverObjects post, serverSwitch env) {
ImagePainter ip = plasmaGrafics.getSearchEventPicture();
if (ip == null) return new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); // empty image
return ip.toImage(true);
}
}

@ -109,7 +109,9 @@ from 'late' peers.
<p>
#(resultbottomline)#
::
The global search resulted in #[globalresults]# link contributions from other YaCy peers
The global search resulted in #[globalresults]# link contributions from other YaCy peers.<br><br>
The Network grafic below shows where the search query was solved by asking corresponding peers in the DHT:
<img src="SearchEventPicture.png">
::
You can enrich the search results by using the 'global' option: This will search also other YaCy peers
::

@ -454,7 +454,7 @@ public final class httpdFileHandler extends httpdAbstractHandler implements http
//File targetClass = rewriteClassFile(targetFile);
Date targetDate;
if ((targetClass != null) && ((path.endsWith("png") || (path.endsWith("gif"))))) {
if ((targetClass != null) && (path.endsWith("png"))) {
// call an image-servlet to produce an on-the-fly - generated image
BufferedImage bi = null;
try {

@ -0,0 +1,235 @@
// plasmaGrafics.java
// -----------------------
// part of YaCy
// (C) by Michael Peter Christen; mc@anomic.de
// first published on http://www.anomic.de
// Frankfurt, Germany, 2005
// Created 08.10.2005
//
// $LastChangedDate: 2005-10-22 15:28:04 +0200 (Sat, 22 Oct 2005) $
// $LastChangedRevision: 968 $
// $LastChangedBy: theli $
//
// 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.plasma;
import java.awt.image.BufferedImage;
import java.util.Iterator;
import java.util.Enumeration;
import java.util.Date;
import de.anomic.tools.ImagePainter;
import de.anomic.yacy.yacyCore;
import de.anomic.yacy.yacySeed;
import de.anomic.yacy.yacySearch;
public class plasmaGrafics {
private static int shortestName = 10;
private static int longestName = 12;
private static ImagePainter networkPicture = null;
private static long networkPictureDate = 0;
public static ImagePainter getSearchEventPicture() {
if (plasmaSearchEvent.lastEvent == null) return null;
yacySearch[] searches = plasmaSearchEvent.lastEvent.getSearchThreads();
if (searches == null) return null; // this was a local search and there are no threads
// get a copy of a recent network picture
ImagePainter eventPicture = (ImagePainter) getNetworkPicture(120000).clone();
// get dimensions
int cr = Math.min(eventPicture.getWidth(), eventPicture.getHeight()) / 5 - 20;
int cx = eventPicture.getWidth() / 2;
int cy = eventPicture.getHeight() / 2;
String hash;
int angle;
// draw in the search peers
for (int j = 0; j < searches.length; j++) {
eventPicture.setColor((searches[j].isAlive()) ? ImagePainter.ADDITIVE_RED : ImagePainter.ADDITIVE_GREEN);
hash = searches[j].target().hash;
angle = (int) ((long) 360 * (yacySeed.dhtPosition(hash) / (yacySeed.maxDHTDistance / (long) 10000)) / (long) 10000);
eventPicture.arcLine(cx, cy, cr - 20, cr, angle);
}
// draw in the search target
plasmaSearchQuery query = plasmaSearchEvent.lastEvent.getQuery();
Iterator i = query.queryHashes.iterator();
eventPicture.setMode(ImagePainter.MODE_ADD);
eventPicture.setColor(ImagePainter.ADDITIVE_BLACK);
while (i.hasNext()) {
hash = (String) i.next();
angle = (int) ((long) 360 * (yacySeed.dhtPosition(hash) / (yacySeed.maxDHTDistance / (long) 10000)) / (long) 10000);
eventPicture.arcLine(cx, cy, cr - 20, cr, angle);
}
return eventPicture;
}
public static ImagePainter getNetworkPicture(long maxAge) {
return getNetworkPicture(maxAge, 640, 480, 300, 300, 1000);
}
public static ImagePainter getNetworkPicture(long maxAge, int width, int height, int passiveLimit, int potentialLimit, int maxCount) {
if ((networkPicture == null) || ((System.currentTimeMillis() - networkPictureDate) > maxAge)) {
drawNetworkPicture(width, height, passiveLimit, potentialLimit, maxCount);
}
return networkPicture;
}
private static void drawNetworkPicture(int width, int height, int passiveLimit, int potentialLimit, int maxCount) {
int innerradius = Math.min(width, height) / 5;
int outerradius = innerradius + innerradius * yacyCore.seedDB.sizeConnected() / 100;
if (outerradius > innerradius * 2) outerradius = innerradius * 2;
if (yacyCore.seedDB == null) return; // no other peers known
int size = yacyCore.seedDB.sizeConnected();
if (size == 0) return; // no other peers known
networkPicture = new ImagePainter(width, height, "000010");
networkPicture.setMode(ImagePainter.MODE_ADD);
// draw network circle
networkPicture.setColor("008020");
networkPicture.arc(width / 2, height / 2, innerradius - 20, innerradius + 20, 0, 360);
//System.out.println("Seed Maximum distance is " + yacySeed.maxDHTDistance);
//System.out.println("Seed Minimum distance is " + yacySeed.minDHTNumber);
yacySeed seed;
int angle;
long lastseen;
// draw connected senior and principals
int count = 0;
int totalCount = 0;
Enumeration e = yacyCore.seedDB.seedsConnected(true, false, null);
while (e.hasMoreElements() && count < maxCount) {
seed = (yacySeed) e.nextElement();
if (seed != null) {
drawNetworkPicturePeer(networkPicture, width / 2, height / 2, innerradius, outerradius, seed, "000040", "608860", "B0FFB0");
count++;
}
}
totalCount += count;
// draw disconnected senior and principals that have been seen lately
count = 0;
e = yacyCore.seedDB.seedsSortedDisconnected(true, yacySeed.LASTSEEN);
while (e.hasMoreElements() && count < maxCount) {
seed = (yacySeed) e.nextElement();
if (seed != null) {
lastseen = Math.abs((System.currentTimeMillis() - seed.getLastSeenTime()) / 1000 / 60);
if (lastseen > passiveLimit) break; // we have enough, this list is sorted so we don't miss anything
drawNetworkPicturePeer(networkPicture, width / 2, height / 2, innerradius, outerradius, seed, "101010", "401000", "802000");
count++;
}
}
totalCount += count;
// draw juniors that have been seen lately
count = 0;
e = yacyCore.seedDB.seedsSortedPotential(true, yacySeed.LASTSEEN);
while (e.hasMoreElements() && count < maxCount) {
seed = (yacySeed) e.nextElement();
if (seed != null) {
lastseen = Math.abs((System.currentTimeMillis() - seed.getLastSeenTime()) / 1000 / 60);
if (lastseen > potentialLimit) break; // we have enough, this list is sorted so we don't miss anything
drawNetworkPicturePeer(networkPicture, width / 2, height / 2, innerradius, outerradius, seed, "202000", "505000", "A0A000");
count++;
}
}
totalCount += count;
// draw my own peer
drawNetworkPicturePeer(networkPicture, width / 2, height / 2, innerradius, outerradius, yacyCore.seedDB.mySeed, "800000", "AAAAAA", "FFFFFF");
// draw description
networkPicture.setColor("FFFFFF");
networkPicture.setMode(ImagePainter.MODE_ADD);
networkPicture.print(2, 8, "THE YACY NETWORK", true);
networkPicture.print(2, 16, "DRAWING OF " + totalCount + " SELECTED PEERS", true);
networkPicture.print(width - 2, 8, "SNAPSHOT FROM " + new Date().toString().toUpperCase(), false);
// set timestamp
networkPictureDate = System.currentTimeMillis();
}
private static void drawNetworkPicturePeer(ImagePainter img, int x, int y, int innerradius, int outerradius, yacySeed seed, String colorDot, String colorLine, String colorText) {
String name = seed.getName().toUpperCase();
if (name.length() < shortestName) shortestName = name.length();
if (name.length() > longestName) longestName = name.length();
int angle = (int) ((long) 360 * (seed.dhtPosition() / (yacySeed.maxDHTDistance / (long) 10000)) / (long) 10000);
//System.out.println("Seed " + seed.hash + " has distance " + seed.dhtDistance() + ", angle = " + angle);
int linelength = 20 + outerradius * (20 * (name.length() - shortestName) / (longestName - shortestName) + (Math.abs(seed.hash.hashCode()) % 20)) / 60;
if (linelength > outerradius) linelength = outerradius;
int dotsize = 6 + 2 * (int) (seed.getLinkCount() / 500000L);
if (dotsize > 18) dotsize = 18;
img.setMode(ImagePainter.MODE_ADD);
// draw dot
img.setColor(colorDot);
img.arcDot(x, y, innerradius, angle, dotsize);
// draw line to text
img.setColor(colorLine);
img.arcLine(x, y, innerradius + 18, innerradius + linelength, angle);
// draw text
img.setColor(colorText);
img.arcPrint(x, y, innerradius + linelength, angle, name);
// draw corona around dot for crawling activity
int ppm10 = seed.getPPM() / 10;
if (ppm10 > 0) {
if (ppm10 > 3) ppm10 = 3;
// draw a wave around crawling peers
long strength;
img.setMode(ImagePainter.MODE_SUB);
img.setColor("303030");
img.arcArc(x, y, innerradius, angle, dotsize + 1, dotsize + 1, 0, 360);
int waveradius = innerradius / 2;
for (int r = 0; r < waveradius; r++) {
strength = (waveradius - r) * (long) (0x08 * ppm10 * (1.0 + Math.sin(Math.PI * 16 * r / waveradius))) / waveradius;
//System.out.println("r = " + r + ", Strength = " + strength);
img.setColor((strength << 16) | (strength << 8) | strength);
img.arcArc(x, y, innerradius, angle, dotsize + r, dotsize + r, 0, 360);
}
}
}
}

@ -57,6 +57,8 @@ import de.anomic.yacy.yacySearch;
public final class plasmaSearchEvent {
public static plasmaSearchEvent lastEvent = null;
private serverLog log;
private plasmaSearchQuery query;
private plasmaWordIndex wordIndex;
@ -84,6 +86,14 @@ public final class plasmaSearchEvent {
this.searchThreads = null;
}
public plasmaSearchQuery getQuery() {
return query;
}
public yacySearch[] getSearchThreads() {
return searchThreads;
}
public plasmaSearchResult search() {
// combine all threads
@ -116,6 +126,7 @@ public final class plasmaSearchEvent {
// return search result
log.logFine("SEARCHRESULT: " + profileLocal.reportToString());
lastEvent = this;
return result;
} catch (IOException e) {
return null;
@ -134,6 +145,7 @@ public final class plasmaSearchEvent {
// return search result
log.logFine("SEARCHRESULT: " + profileLocal.reportToString());
lastEvent = this;
return result;
} catch (IOException e) {
return null;

@ -58,7 +58,7 @@ import java.awt.image.WritableRaster;
import java.util.HashSet;
import java.util.ArrayList;
public class ImagePainter {
public class ImagePainter implements Cloneable {
// colors regarding RGB Color Model
public static final long ADDITIVE_RED = 0xFF0000;
@ -133,6 +133,24 @@ public class ImagePainter {
return s;
}
public Object clone() {
ImagePainter ip = new ImagePainter(this.width, this.height, 0);
System.arraycopy(this.grid, 0, ip.grid, 0, this.grid.length);
ip.defaultColR = this.defaultColR;
ip.defaultColG = this.defaultColG;
ip.defaultColB = this.defaultColB;
ip.defaultMode = this.defaultMode;
return ip;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void setColor(long c) {
defaultColR = (int) (c >> 16);
defaultColG = (int) ((c >> 8) & 0xff);

@ -106,6 +106,10 @@ public class yacySearch extends Thread {
return this.profile;
}
public yacySeed target() {
return targetPeer;
}
private static yacySeed[] selectPeers(Set wordhashes, int seedcount) {
// find out a specific number of seeds, that would be relevant for the given word hash(es)
// the result is ordered by relevance: [0] is most relevant

@ -376,7 +376,7 @@ public class yacySeed {
return s;
}
public long decodeLex(String s) {
public static long decodeLex(String s) {
long c = 0;
for (int i = 0; i < s.length(); i++) {
c = c * 96 + (byte) s.charAt(i) - 32;
@ -414,9 +414,14 @@ public class yacySeed {
return (myPos > wordPos) ? (myPos - wordPos) : (myPos + maxDHTDistance - wordPos);
}
public long dhtDistance() {
public long dhtPosition() {
// returns an absolute value
return decodeLex(hash.substring(0,9)) - minDHTNumber;
return dhtPosition(this.hash);
}
public static long dhtPosition(String ahash) {
// returns an absolute value
return decodeLex(ahash.substring(0,9)) - minDHTNumber;
}
public static yacySeed genLocalSeed(plasmaSwitchboard sb) {

Loading…
Cancel
Save