IOException.de

Icon

Ausgewählter Nerdkram von Informatikstudenten der Uni Ulm

Barrier points in Node.js

Node.js ist ein serverseitiges, hochskalierbares Framework für die Entwicklung von asynchronen Netzwerkanwendungen in JavaScript. Aufgrund der Asynchronität ist das Framework in der Lage, tausende Verbindung gleichzeitig offen zu halten und zu verarbeiten. Ein wesentliches Merkmal hier von ist, dass ausschließlich mit Callbacks gearbeitet wird, um auf Beendigungen von Operationen zu reagieren.

Im Normalfall führt das zu einem Chaining von Callback. Im folgenden Beispiel sollen zwei Dateien geöffnet werden und ihr kompletter Inhalt zurückgegeben werden:

var size = 0;

fs.readFile('/home/benjamin/file1', function(err, data)
{
	if (!err)
	{
		// first file read
		size += data.length;
		fs.readFile('/home/benjamin/file2', function(err, data)
		{
			if (!err)
			{
				// second file read
				size += data.length;
				fs.writeFile('/home/benjamin/size', size, function(err)
				{
					if (!err)
					{
							// both file read and content written to file
							sys.log('done');
						}
					});
			}
		});
	}
});

Das Problem hierbei ist, dass zwei Aktionen, die eigentlich parallel ablaufen könnten, nämlich das lesen beider Dateien, nacheinander ablaufen müssen. Für einen parallelen Ablauf ist eine zusätzliche Koordination notwendig, da die Resultate beider Aufrufe in Verbindung stehen. Hierfür habe ich mich an den CyclicBarrier Klassen von Java orientiert und eine einfache Klasse für die Koordination von asynchronen Callbacks geschrieben. Eine Barriere wird erzeugt unter Angabe der Anzahl von teilnehmenden Parties. Desweiteren können optional ein Callback für die Beendigung sowie ein optionaler Callback im Abbruchsfall registriert werden. Anschließend können die einzelnen Aufgaben der Parties angestoßen werden. Im Erfolgsfall müssen diese an der Barriere mit submit() anzeigen, dass sie beendet sind. Durch abort() kann auch ebenfalls ein Abbruch signalisiert werden. Eine Propagation der Ergebnisdaten lässt am besten durch eine externe Variable realisieren, auf den die Funktionen ebenfalls Zugriff haben.

Der Code des Beispielszenarios ändert sich dann wie folgt:

var size = 0;

var b = new Barrier(2, function()
{
	//Success callback
	fs.writeFile('/home/benjamin/size', size, function(err)
	{
		sys.log('done');
	});
}, function()
{
	//Aborted callback
	sys.log("aborted");
});

fs.readFile('/home/benjamin/file1', function(err, data)
{
	if (err)
	{
		b.abort();
	}
	else
	{
		size += data.length;
		b.submit();
	}
});

fs.readFile('/home/benjamin/file2', function(err, data)
{
	if (err)
	{
		b.abort();
	}
	else
	{
		size += data.length;
		b.submit();
	}
});

Wie im Vergleich zu erkennen ist, lässt sich die Ausführung deutlich beschleunigen. Ein paar Rahmenbedingungen gibt es jedoch. Zunächst dürfen die Teilaufgaben keine Abhängigkeiten untereinander besitzen. Dann darf ein Abbruch einer Teilaufgabe keine Auswirkung auf noch laufende Teilaufgaben besitzen, dessen Ergebnis später verworfen wird. Schließlich muss bei der Programmierung darauf geachtet werden, dass in jedem Fall eine Teilaufgabe mit submit() oder abort() terminiert, da ansonsten ein Lock entsteht.

Die Klasse ist relativ einfach:

/**
 * @class
 *
 * Creates a new barrier for the given amount of parties.
 * @param parties
 * @param barrierCallback
 * @param abortCallback
 * @return
 */
var Barrier =  function(parties, barrierCallback, abortCallback)
{
	this.parties = parties;
	this.barrierCallback = barrierCallback;
	this.abortCallback = abortCallback;

	this.running = true;
	this.count = 0;
};

/**
 * Signals a completion of one of the parties.
 * @return
 */
Barrier.prototype.submit = function()
{
	if (++this.count === this.parties && this.running)
	{
		this.barrierCallback();
	}
};

/**
 * Signals an abort by one of the parties. If not callback is passed, the default abort callback will be executed.
 * @param customAbortCallback Optional callback that should be executed due to the abort.
 * @return
 */
Barrier.prototype.abort = function(customAbortCallback)
{
	if (this.running && customAbortCallback)
	{
		customAbortCallback();
	}
	else if (this.running && this.abortCallback)
	{
		this.abortCallback();
	}
	this.running = false;
};

Klasse auf github: http://gist.github.com/464179

Histogramplot in Sage/Matplotlib

Wer Matlab mag wird Sage lieben, insbesondere wenn die Ausgangsdaten sowieso in Python vorliegen. Ein einfaches Histogram für Ganzzahlen lässt sich wie folgt realisieren:


from sage.all import *
import numpy
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

def plot_hist(subplot,name,x_data,x_var,y_var,b_width):

  #create array
  n_array = numpy.array(x_data)

  #labels
  subplot.set_xlabel('variable '+x_var+' [min = '+str(n_array.min())+', max='+str(n_array.max())+' ]')
  subplot.set_ylabel(y_var)

  #create bins
  mmin = n_array.min()
  mmax = n_array.max()
  b = numpy.arange(mmin-(1.0/2),mmax+1+(1.0/2))

  #set ticks
  subplot.set_xticks(b)

  #hist
  n, bins, patches = subplot.hist(x_data,bins=b, rwidth=b_width)

  #title
  subplot.set_title(r'Histogram of '+x_var)

Benutzt wird das Ganze dann mittels:

f = matplotlib.pyplot.figure()
a = f.add_subplot(111)

plot_utils.plot_hist(a,'Decimals', [1,1,1,2,2,3,3,3,4,4,5,5,6,6,7,7],'decimal','# of decimals',0.8)

matplotlib.pyplot.savefig('plot.png')

Atom Feeds in Java mit ROME direkt lesen

Für die Interaktion mit Feeds gibt es in Java die weit verbreitete ROME-Library. Diese Library unterstützt sowohl RSS als auch ATOM in den verschiedenen Versionen. Außerdem bietet es eine Abstraktion an, die den Umgang mit den verschiedenen Feedarten vereinfachen soll. Ihre sogenannten Syndication Feeds bieten eine einheitliche Schnittstelle an, und sind unabhängig vom darunter liegenden Format. Dies mag allgemein sehr hilfreich sein und für viele Fälle auch ausreichen. Typische Operationen sind somit entkoppelt vom Format und können wiederverwendet werden, oder das konkrete Format kann problemlos ausgetauscht werden.

Der Nachteil hierbei ist, dass bei dieser Abstraktion Besonderheiten der einzelnen Formate verborgen werden. Problematisch wird es zum Beispiel, wenn man explizit ein bestimmtes Format lesen möchte, um auf bestimmte Elemente zuzugreifen. So muss in Atom jeder Feed und Einträg ein ID Element besitzen, in RSS existiert dies jedoch nicht. Leider existiert nun auch keine Methode, ein solches Feld in einem Syndication Feed direkt abzufragen.

Nach einigem Suchen bin ich nun auf die Lösung gestoßen. Beim Einlesen des Feeds muss explizit ein Flag aktiviert werden, dass das zugrunde liegende Format ebenfalls mitgespeichert werden soll. Erst wenn dieses Flag gesetzt ist, lässt sich später der Feed im Originalformat (WireFeed) abrufen:

InputSource source = new InputSource(...);
SyndFeedInput feedInput = new SyndFeedInput();
feedInput.setPreserveWireFeed(true);
SyndFeed feed = feedInput.build(source);

Später bietet dann der Syndication Feed Zugriff auf den konkreten Feed:

WireFeed wireFeed = (WireFeed) feed.originalWireFeed();
if(wireFeed instanceof com.sun.syndication.feed.atom.Feed)
{
   String feedId = ((Feed) wireFeed).getId()
}

Kurzpräsentation – Node.js

Auf dem gestrigen Webmontag in Ulm habe ich Node.js vorgestellt, ein Framework für serverseitiges JavaScript für skalierbare Netzwerkanwendungen. Dabei hat es sich um eine eher kurze und oberflächliche Präesentation gehandelt, die die Grundidee des asynchroner I/O Operationen betonen sollte. Detailliertere Beiträge zu Node.js wird es aber hier in Kürze geben.

AF Ubiquitous Computing – Projektskizze ‘MAMPF’

Die Küche ist wohl weiterhin einer der traditionsreichsten Plätze in der modernen Gesellschaft. Auch wenn es Feministinnen nicht gefallen wird, so steht „Oma“ für ein Qualitätsmerkmal im Bereich der zünftigen Küche. Handschriftliche Rezeptsammlungen sind auch heute noch in modernen Küchen zu finden. Dabei handelt es sich nicht selten um über Generationen gesammelte Werke. Als Kind lernt man meist schon durch Selbstversuch, dass der Topf über eine Herdplatte erwärmt wird und lernt so recht schnell wie unsere Gesellschaft zu warmen Speisen gelangt.

Mit unserem Projekt wollen wir das Kochen nicht neu erfinden. Vielmehr handelt es sich bei der Multifunctional and Adaptive Meal Preparation Facility (MAMPF) um ein Konzept, welches zeigen soll, dass ubiquitäre Unterstützung auch im Bereich der Küche sinnvoll einzubringen ist. Dafür möchten wir einige der festgefahrenen Methoden aufbrechen und uns überlegen, wie diese sinnvoll zu verändern bzw. zu erweitern sind. Oft beschränkt sich ein Haushalt auf eine gut abzählbare Menge von immer wiederkehrenden Gerichten. Dies hat zum Einen den Grund, dass diese Gerichte Lieblingsspeisen sind, zum Anderen liegt dies an Zeit- und Motivationsmängel, sich die Zubereitung eines neuen Gerichtes anzueignen.
Durch ein System, welches Rezepte bereitstellt und Unterstützung für den Kochvorgang anbietet, kann möglicherweise diese Hürde etwas herabgesetzt werden. Durch maschinenlesbare Rezepte lassen sich auch sehr einfach Inhaltsstoffe überprüfen, beispielsweise zur Vermeidung von Unverträglichkeiten beziehungsweise Allergien oder für eine gesündere Ernährung.

Ein solches Format bringt neben der Möglichkeit zur Kochunterstützung eine Fülle weiterer Eigenschaften. So können Rezepte sehr gut kategorisiert, durchsucht, getauscht, bewertet oder modifiziert werden. Damit wäre es auch möglich Rezepte über eine Online-Plattform für andere zugänglich zu machen. Die klassische Bedienung soll so verändert werden, dass eine einfachere Handhabung möglich ist. Ein Kochvorgang zum Aufkochen von Wasser beginnt meistens, indem man einen Topf mit Wasser füllt, sich eine geeignete Platte auf dem Herd aussucht und anschließend das Bedienelement für diese Platte auf die höchste Stufe stellt.
Bei unserem Konzept soll vor Allem diese letzte Indirektionsstufe wegfallen, indem das System sowohl weiß, wo sich das Kochgeschirr befindet, als auch, wie dieses anzusteuern ist. Dies nennt sich dann ‘zoneless cooking’.

Es handelt sich in diesem Punkt um eine Machbarkeitsstudie, da wir aus Kostengründen keine große Fläche aus vielen kleinen Induktionsspulen zur Verfügung haben. Derartige Produkte werden auch von den großen Firmen erforscht, die leider nicht an einer Beteiligung an diesem Projekt interessiert waren. Daher wird mit drei einfachen Induktionskochplatten das Prinzip der Topferkennung und des gezielten Ansteuerns umgesetzt, welches auf eine großflächige Induktionsmatrix übertragbar ist.

Die MAMPF stellt dann schließlich ein vielseitiges Küchensystem dar, das den Benutzer bei Bedarf in weiten Teilen unterstützt. Dies bedeutet, dass der Benutzer des Systems in keinster Weise in seinen Möglichkeiten eingeschränkt werden soll und auch künftig in gewohnter Weise kochen kann. Die gebotene Unterstützung umfasst mehrere Bereiche wie erhöhte Sicherheit, einen neuen Ansatz der Interaktion sowie Begleitung durch Rezepte.

Die Darstellung des Systemzustandes, sowie aller Anweisungen für ein Rezept, werden auf einem Monitor über der Kochplatte angezeigt. Bedient wird das System über einen in die Kochplatte eingelassenen, berührungsempfindlichen TabletPC. Die Bedienfläche ist somit von der Ausgabe getrennt, kann aber auch die Ausgabe für eine direkte Interaktion darstellen. Hiermit ist es möglich auch von entfernten Geräten auf die Kocheinheit zuzugreifen und Änderungen am System durchzuführen.

Mithilfe einer Datenbank sollen Benutzerinformationen gesammelt werden. Diese Informationen erlauben später eine genauere Berechnung der benötigten Kochdauer oder das sortieren von bestimmten Rezepten.

Um dieses Projekt zu realisieren, wird wie bereits erwähnt auf die Technik der Induktion gesetzt. Die Kochplatten werden durch Hardwarenahe-Programmierung über Mikrocontroller angesprochen. Des Weiteren verwenden wir Algorithmen aus der Computer Vision zur Objekterkennung und -tracking, ein selbst spezifiziertes Rezeptformat und ein hohes Maß an Modularität durch die Common Application Library (CAL) des .NET-Frameworks in Verbindung mit dem Model-View-ViewModel-Pattern. Durch dieses Lose-gekoppelte Framework ist es möglich mit fünf Personen unabhängig von den Arbeitsfortschritten der anderen zu entwickeln.

Die Motivation MAMPF umzusetzen besteht darin das Kochen zu vereinfachen. Ungeübte Köche und komplizierte Rezepte sollen nicht mehr im Widerspruch zueinander stehen.

Beamer im Eigenbau – Teil 3

Nach langer Zeit melde ich mich zu diesem Thema auch mal wieder. Seit dem letzten Mal hat sich leider nicht viel an meinem Beamer verändert, da ich nach wie vor vor dem großen Problem, DVI zu LVDS oder VGA zu LVDS wandlen, stehe. Allerdings ist dies auch das einzige Problem, das ich hab. Würde das gelöst werden, könnte ich alles nehmen und in einer kleinen Kiste zusammenführen, um einen anständigen Beamer zu haben.

Trotz mehr oder weniger profesorischem Gehäuse, haben wir den Beamer in den letzten Monaten auf sein Durchhaltevermögen getestet. Hauptsächlich normale Videoabende. Jedoch haben wir uns es nicht nehmen lassen, das Champions League Finale darauf anzuschauen. Aber nicht nur das, sondern davor noch Halbfinale Eishockey-WM und danach noch bis halb 3Uhr Nachts weiter getestet.  Somit haben wir an diesem Abend eine Laufzeit von ca. 7h erzielt. Es traten keinerlei Probleme auf, eine dezente Hitzeentwicklung war zwar vorhanden aber nicht weiter wild, und wir haben auf eine Diagonale von ca 3m Fußball und Co geschaut.

Bisheriges Fazit: Auch wenn ich noch nicht das Optimum aus dem Ding geholt habe, bin ich damit sehr zufrieden und er hat bisher alles mitgemacht. Außerdem hab ich nun einen HD-Ready Beamer für wenig Geld und hab ihn selbst gebastelt. Dies ist viel toller als irgendwas zu kaufen.

Teamprojekt Humanoid-Roboter (The Birth)

Im Laufe eines Studiums muss man ja diverse Praktika machen. Eines davon steht dieses Semester nun auch bei mir an. Nachdem ich lange überlegt hab, ob für einen Nebenfach Medizin Informatiker nun OS im Eigenbau, Autonomous Underwater Vehicle oder Humanoid-Roboter am besten sei, entschied ich mich für letzteres.

Hierbei geht es um einen kleinen Graupner Humanoiden der Serie RB-1000. Diesem Humanoiden, getauft auf T-1000 aka Arnie, müssen wir in einem Teamprojekt das Gehen beibringen.

Arnie hat 21 Servos, 2 LED-Augen(rot) und einen Microkontroller, der an der Uni eigenständig entwickelt wurde, versehen mit einer Bluetooth-Schnittstelle und einem Gyroskop. In zwei Praktika zuvor wurden zwei Interfaces entwickelt, das eine in MatLab und das andere in C/C++. Derzeit können wir uns noch nicht ganz entscheiden, welches von beiden wir verwenden werden. Allerdings ist mir das C/C++ gerade noch lieber, da es weniger Probleme bereitet und von uns in – welch Einfalssreichtum – Skynet umbenannt wurde. Das schöne dabei ist, dass man beispielsweise ein Bashscript schreiben kann für die Ansteuerung und dann das ganze einfach an Skynet pipen kann.

Bisher bestand unsere Tätigkeit darin, Arnie erst einmal komplett zu entrümpeln. Wir haben unnötige Meter an Servokabel entfernt, die Stromversorgung neu angeschlossen, neue Schalter angebracht, die Batterie im Brustkorb durch ein passendes Netzteil ersetzt, was uns die Handhabung um mindestens 120% verbessert, die Interfaces gestestet und vorbereitet. Demnächst werden wir auch noch eine kleine Justierungsstation basteln, damit man ihn vor Inbetriebnahme immer optimal einstellen kann.

Natürlich haben wir auch schon ordentlich an ihm getestet was er kann und wie es geht. Hier sieht man ihn, wie er winkt.

This is only the beginning….

AF Ubiquitous Computing – Projektskizze ‘diretto’

Heutige Mobilgeräte wie Smartphones, Netbooks oder PDAs stellen zu einem großen Teil drahtlosen Zugriff auf das Internet bereit. Zugleich bieten diese Geräte häufig auch die Möglichkeit, multimediale Inhalte wie Bilder, Videos oder Tonmitschnitte überall zu produzieren. Alternativ können sie zumindest als Brücke ins Internet fungieren und dedizierte Geräte wie Digitalkameras anbinden.

Trotz dieser theoretischen Möglichkeiten existieren bisher kaum Anwendungen, die mithilfe dieser Technologien eine multimediale Berichterstattung in quasi Echtzeit ermöglichen. Das Ziel des diretto-Projektes ist es, eine solche Plattform zu entwickeln und Beispiellösungen für die Integration mobiler Geräte aufzuzeigen. Zusätzlich zu Sammlung der mutlimedialen Inhalte liegt ein weiter Fokus auf der Analyse, Bewertung und Verbesserung der erhaltenen Daten – sowohl durch das System als auch durch die Benutzer selbst. So kann zum Beispiel die Genauigkeit von Metadaten wie Orts- und Zeitangaben verbessert werden, Beiträge können mithilfe von Tags klassifiziert und verschiedene mutlimediale Inhalte untereinander sinnvoll verlinkt werden. Durch das System erzeugte Gruppierungen unterstützen den Benutzer zusätzlich bei der Auswertung der Inhalte.

Als Grundlage für das komplette Projekte werden zeitgemäße Web-Technologien eingesetzt. Somit ist die Plattform offen, sehr leicht erweiterbar und skaliert auch bei der Nutzung in größeren Szenarien. Die API steht in Form eines REST-konformen Webservices zur Verfügung. Metadaten werden im leichtgewichtigen JSON-Format kodiert. Ein spezieller PubSubHubbub-Endpunkt ermöglicht Benachrichtigungen über neue Inhalte in Echtzeit. Dezentrale Zusatzdientse steuern zusätzliche Funktionalitäten bei.

Eine mächtige Weboberfläche bietet Zugriff auf die Gesamtheit der erhobenen Daten – auch entfernt über das Internet. Sie bietet die Grundlage für komplexe Auswertungen der vorhandenen Multimediadaten und zugehörigen Metadaten. Im Vordergrund steht hierbei auch die Unterstützung des Benutzers beim Umgang mit den vieldimensionalen Daten.

Für die Integration mobiler Systeme werden verschiedene Clients entwickelt und erprobt. Ein Smartphone-Client erlaubt es dem Besitzer eines Smartphones direkt zum Reporter vor Ort zu werden und Inhalte beizusteuern. Für die Anbindung dedizierter Hardware wie einer digitalen Spiegelreflexkamera wird eine besondere Lösung erabreitet. Ein mobiler Rechner im Rucksack soll als Uplink-Gerät dienen und frisch geschossene Bilder ohne Verzögerung direkt auf die Plattform hochladen. Mithilfe einer solchen Lösung können Fotojournalisten als echte Live-Berichterstatter agieren und Pausen für den Upload entfallen.

Eine solche Plattform eignet sich je nach Ausrichtung für eine Vielzahl verschiedener Einsatzszenarien. So könnte es zur Live-Dokumentation großer Ereignisse dienen. In einem geschlossenen Kontext könnte es Einsatzkräfte bei Großschadenslagen dabei helfen, in kürzerer Zeit einen detaillierteren Überblick zu bekommen und unterstützende Kräfte zur Auswertung fernab einbinden.

Das Projekt wurde im Rahmen des Anwendungsfaches Ubiquitous Computing an der Universität Ulm von einem studentischen Team entworfen und nun in Zusammenarbeit mit einem Team für Interaktive Systeme als Prototyp realisiert. Nähere Informationen gibt es auf der Projektseite www.diretto.org

Anwendungsfachprojekte Ubiquitous Computing

Als Student im Diplomstudiengang Medieninformatik an der Uni Ulm ist es Bestandteil des Hauptstudiums, ein Anwendungsfach aus den Teilgebieten der Medien-Informatik zu belegen. Hierbei stehen unter anderem Vertiefungsrichtungen wie Computergrafik, Computer Vision, Ubiquitous Computing, Medienpädagogik, Interaktive Systeme, Interaktives Video oder Mensch-Maschine Dialogsysteme zur Auswahl.

Ubiquitous Computing steht für den Trend hin zum allgegenwärtigen Computer oder dem „Internet der Dinge“. Ob als intelligenter Kühlschrank, im vernetzten Auto oder in Form von intelligenten Smartphones, der Computer und mit ihm oft auch das Internet werden immer allgegenwärtiger und verschmelzen mit der Umgebung. Das Anwendungsfach besteht einerseits aus den Vorlesungen Multimediasysteme und Mobile & Ubiquitous Computing, und andererseits aus einer wissenschaftlichen Projektarbeit über zwei Semester in Gruppen.

Verschiedene Autoren des Blogs arbeiten derzeit gemeinsam an solchen Projekten und werden diese hier genauer vorstellen.

LRU-Cache in Java

Caches dienen in der Informatik als Methode, Zugriffe auf bestimmte Daten zu beschleunigen, in dem diese vorgelagert/gepuffert werden. Sie sind in verschiedensten Bereichen zu finden, unter anderem auf Prozessoren, in Festplatten, aber auch in Technologien wie dem Web. Verschiedene Verdrängungsstrategien ermöglichen es, die beschränkte Kapazität eines Caches zu berücksichtigen, so dass nur wichtige Werte im Cache gelagert werden. Least Recently Used (LRU), ist eine solche Strategie, die häufig angewandt wird. Sie sortiert die Werte im Cache nach der letzten Nutzung. Wird auf ein Element über einen längeren Zeitraum nicht mehr zugegriffen, so wird es aus dem Cache verdrängt.

In Java lässt sich ein solcher LRU-Cache besonders einfach implementieren, da die Klasse java.util.LinkedHashMap bereits die wesentlichen Mechanismen unterstützt. Eine HashMap ist eine Hash-Tabelle, die Zugriffe auf Werte über ihre Schlüssel regelt. Zusätzlich verkettet die LinkedHashMap aber die Werte noch in einer Liste, womit auch eine Traversierung in Einfügereihenfolge ermöglicht wird. Mithilfe eines Flags in einem der Konstruktoren kann dieses Verhalten geändert werden, so dass bei jedem Zugriff das angesprochene Element neu in diese Liste eingereiht wird. Damit verwaltet die Liste die Zugriffe und ist Basis für die LRU-Strategie.

Die Methode removeEldestEntry() der LinkedHashMap wird bei jedem Schreibezugriff auf die Map, also nach Einfügeoperationen über put() oder putAll() automatisch aufgerufen und bietet die Möglichkeit, durch Überschreiben der Methode die Verdrängungsstrategie zu implementieren. Diese Methode gibt ein boolean zurück, ob der älteste Eintrag gelöscht werden soll. Es ist auch möglich, innerhalb der Methode selbst die Liste zu manipulieren, dann sollte allerdings die Methode immer false zurückgeben. Für den LRU-Cache reicht es aus, die Größe der Map mit dem gewünschten Maximum zu vergleichen. Ist der Inhalt der Map zu groß, so soll das letzte Element gelöscht werden.

Im Folgenden nun der Code dazu. Zu beachten ist noch, dass es sich um eine threadsichere Klasse handelt, da die Map explizit synchronisiert wird.

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * A thread-safe LRU cache implementation based on internal LinkedHashMap.
 *
 * @author Benjamin Erb
 *
 * @param <K> Entry Key Type
 * @param <V> Entry Value Type
 */
public class LRUCache<K, V>
{
	public static final int DEFAULT_MAX_SIZE = 1000;

	private final Map<K, V> internalMap;

	public LRUCache()
	{
		this(DEFAULT_MAX_SIZE);
	}

	public LRUCache(final int maxSize)
	{
		this.internalMap = (Map<K, V>) Collections.synchronizedMap(new LinkedHashMap<K, V>(maxSize + 1, .75F, true)
		{
			private static final long serialVersionUID = 5369285290965670135L;

			@Override
			protected boolean removeEldestEntry(Map.Entry<K, V> eldest)
			{
				return size() > maxSize;
			}
		});
	}

	public V put(K key, V value)
	{
		return internalMap.put(key, value);
	}

	public V get(K key)
	{
		return internalMap.get(key);
	}

}

ioexception.de

Benjamin Erb studiert seit 2006 Medieninformatik und interessiert sich insbesondere für Java, Web-Technologien, Ubiquitous Computing, Cloud Computing, verteilte Systeme und Informationsdesign.


Raimar Wagner studiert seit 2005 Informatik mit Anwendungsfach Medizin und interessiert sich für C++ stl, boost & Qt Programmierung, Scientific Visualization, Computer Vision und parallele Rechenkonzepte.


David Langer studiert seit 2006 Medieninformatik und interessiert sich für Web-Entwicklung, jQuery, Business Process Management und Java.


Sebastian Schimmel studiert seit 2006 Informatik mit Anwendungsfach Medizin und interessiert sich für hardwarenahe Aspekte, Robotik, webOs, C/C++ und UNIX/Linux.


Timo Müller studiert seit 2006 Medieninformatik. Er interessiert sich allen voran für Mobile and Ubiquitous Computing, systemnahe Enwticklung und verteilte Systeme, sowie Computer Vision.


Achim Strauß studiert seit 2006 Medieninformatik. Seine Interessen liegen in Themen der Mensch-Computer Interaktion sowie Webentwicklung und UNIX/Linux.


Tobias Schlecht studiert seit 2006 Medieninformatik und interessiert sich vor allem für Software Engineering, Model Driven Development, Model Driven Architecture, Requirements Engineering, Web-Technologien, UML2 und Java.


Fabian Groh studiert seit 2006 Medieninformatik.

Archiv

Juli 2010
M D M D F S S
« Jun    
 1234
567891011
12131415161718
19202122232425
262728293031