ringbuffer.c-Dateireferenz

Implmentiert einen Ringbuffer in LPC. Mehr ...

#include <util/ringbuffer.h>
Include-Abhängigkeitsdiagramm für ringbuffer.c:

gehe zum Quellcode dieser Datei

Klassen

struct  std_ringbuffer
 Struktur, die einen Ringpuffer speichert. Mehr ...

Makrodefinitionen

#define MAXCOUNT   30
 Standardgroesse fuer Ringbuffer.

Funktionen

protected struct std_ringbuffer CreateRingBuffer (int size, int newmode)
 Erzeugt einen neuen Ringbuffer und liefert ihn zurueck.
protected void RingBufferPut (struct std_ringbuffer buffer, mixed val)
 Schreibt einen neuen Wert in den Ringbuffer.
protected mixed RingBufferGet (struct std_ringbuffer buffer)
 Liefert ein Array mit allen Werten des Ringbuffers buffer.
protected struct std_ringbuffer ResizeRingBuffer (struct std_ringbuffer buf, int size)
 Erzeugt einen neuen Ringbuffer der Groesse size und dem gleichen Modus wie buf, der dieselben Daten enthaelt wie buf.

Ausführliche Beschreibung

Implmentiert einen Ringbuffer in LPC.

Ab und an hat man den Fall, dass man Ereignisse/Meldungen o.ae. hat, von denen man immer genau die letzten x gespeichert und abrufbar vorhalten moechte. Dieses File stellt eine Datenstruktur und dazugehoerige Verwaltungsfunktionen zu Verfuegung, mit denen dies effizient moeglich ist. Insbesondere umgehen diese das staendige Slicing von Arrays, mit denen haeufig Ringpuffer gebaut werden. Hierbei wird das Schreiben in den Puffer billiger, das Abrufen der Daten allerdings teurer. Wird der Puffer haeufiger abgefragt als beschrieben, ist dies keine effiziente Loesung.

Autor:
Zesstra
Datum:
22.05.2008
Version:
$Id$

Definiert in Datei ringbuffer.c.


Makro-Dokumentation

#define MAXCOUNT   30

Standardgroesse fuer Ringbuffer.

Definiert in Zeile 31 der Datei ringbuffer.c.

Wird benutzt von CreateRingBuffer().


Dokumentation der Funktionen

protected struct std_ringbuffer CreateRingBuffer ( int  size,
int  newmode 
) [read]

Erzeugt einen neuen Ringbuffer und liefert ihn zurueck.

Die Funktion erzeugt einen neuen, leeren Ringbuffer der Groesse size und mit Ausgabemodus newmode und liefert die entsprechende Ringbuffer-Struktur zurueck.

Achtung:
Die zurueckgelieferte Datenstruktur bitte nicht per Hand manipulieren.
Parameter:
[in] size Groesse des zu erzeugenden Ringbuffers. Default: 30
[in] newmode Ausgabemodus des Ringbuffers: MODE_FIFO oder MODE_LIFO. Default: MODE_FIFO
Rückgabe:
Der erzeugte Ringbuffer (struct vom Typ std_ringbuffer).
Siehe auch:
ResizeRingBuffer, RingBufferPut, RingBufferGet

Definiert in Zeile 59 der Datei ringbuffer.c.

Benutzt MAXCOUNT, std_ringbuffer::mode, MODE_FIFO, MODE_LIFO, std_ringbuffer::next und std_ringbuffer::rbuffer.

Wird benutzt von ResizeRingBuffer().

00059                                                                         {
00060   
00061   struct std_ringbuffer buffer = (<std_ringbuffer>
00062        rbuffer: allocate(size||MAXCOUNT, 0), 
00063        mode: newmode || MODE_FIFO, 
00064        next: 0 );
00065 
00066   // Bei LIFO von oben anfangen.
00067   if (newmode==MODE_LIFO)
00068     buffer->next = sizeof(buffer->rbuffer);
00069   
00070   return buffer;
00071 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

protected struct std_ringbuffer ResizeRingBuffer ( struct std_ringbuffer  buf,
int  size 
) [read]

Erzeugt einen neuen Ringbuffer der Groesse size und dem gleichen Modus wie buf, der dieselben Daten enthaelt wie buf.

Diese Funktion erzeugt einen neuen Ringbuffer und kopiert alle Daten aus dem alten Puffer in den neuen um.

Parameter:
[in] buf alter Ringbuffer
[in] size gewuenschte neue Groesse
Rückgabe:
Liefert neuen Ringbuffer mit gewuenschten Groesse.
Siehe auch:
CreateRingBuffer, RingBufferPut, RingBufferGet
Achtung:
Wird der Ringbuffer verkleinert, kommt es zum Verlust der aeltesten Daten, die nicht mehr in den neuen hineinpassen.
Noch zu erledigen:
Effizientere Implementation.

Definiert in Zeile 154 der Datei ringbuffer.c.

Benutzt buf, CreateRingBuffer(), RingBufferGet() und RingBufferPut().

00155                                                            {
00156   // neuen Ringbuffer anlegen.
00157   struct std_ringbuffer nbuf = CreateRingBuffer(size, buf->mode);
00158   // und alle daten aus dem alten wieder reinstopfen.
00159   // ja, das geht effizienter, hab ich gerade aber keinen Bock drauf. Die
00160   // Funktion wird vermutlich eh sehr selten gerufen.
00161   foreach(mixed val: RingBufferGet(buf))
00162     RingBufferPut(nbuf, val);
00163   // neuen Buffer zurueckgeben. Der alte bleibt unveraendert!
00164   return nbuf;
00165 }

Hier ist ein Graph der zeigt, was diese Funktion aufruft:

protected mixed RingBufferGet ( struct std_ringbuffer  buffer  ) 

Liefert ein Array mit allen Werten des Ringbuffers buffer.

Das zurueckgelieferte Array enthaelt alle Daten des Ringbuffers in der beim Erstellen des Puffers gewuenschten Reihenfolge (s. MODE_FIFO, MODE_LIFO). Ist der Puffer noch nicht vollstaendig gefuellt, enthalten die bisher noch nie beschriebenen Elemente 0.

Parameter:
[in] buffer Ringpuffer, dessen Daten ausgeben werden sollen.
Rückgabe:
Array mit Daten des Puffers.
Siehe auch:
CreateRingBuffer, RingBufferPut, ResizeRingBuffer

Definiert in Zeile 115 der Datei ringbuffer.c.

Benutzt std_ringbuffer::mode, MODE_LIFO, std_ringbuffer::next und std_ringbuffer::rbuffer.

Wird benutzt von ResizeRingBuffer().

00115                                                             {
00116   int size = sizeof(buffer->rbuffer);
00117   int next = buffer->next;
00118   mixed rbuffer = buffer->rbuffer;
00119 
00120   switch(buffer->mode) {
00121     case MODE_LIFO:
00122       // der hintere Teil enthaelt die neueren Daten. Die kommen zuerst.
00123       // Wenn next == sizeof(), dann kann das interne Array einfach kopiert
00124       // werden.
00125       if (next == size)
00126                 return copy(rbuffer);
00127       else
00128                 return rbuffer[next .. size-1] + rbuffer[0 .. next-1];
00129     default:
00130       // der vordere Teil enthaelt die neueren Daten. Also zuerst den hinteren
00131       // ausgeben, dann den vorderen.
00132       // Wenn next 0, kann das interne Array einfach kopiert werden. Sonst
00133       // muss es zusammengesetzt werden.
00134       if (next)
00135                 return rbuffer[next .. size-1] + rbuffer[0 .. next-1];
00136       else
00137                 return copy(rbuffer);
00138   }
00139   return 0;
00140 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

protected void RingBufferPut ( struct std_ringbuffer  buffer,
mixed  val 
)

Schreibt einen neuen Wert in den Ringbuffer.

Diese Funktion schreibt einen neuen Wert in den Ringbuffer buffer und loescht dabei ggf. den aeltesten Wert im Puffer.

Parameter:
[in,out] buffer zu aendernder Ringbuffer
[in] val hinzuzufuegender Wert
Siehe auch:
CreateRingBuffer, ResizeRingBuffer, RingBufferGet

Definiert in Zeile 80 der Datei ringbuffer.c.

Benutzt std_ringbuffer::mode, MODE_LIFO, std_ringbuffer::next und std_ringbuffer::rbuffer.

Wird benutzt von ResizeRingBuffer().

00080                                                                       {
00081   int next = buffer->next;
00082   // je nach Ausgabemodus von oben nach unten oder von unten nach oben die
00083   // Werte reinschreiben.
00084   switch(buffer->mode) {
00085     case MODE_LIFO:
00086       // next ist hier eigentlich ein 'last'. Dekrementieren und dann zum
00087       // Indizieren benutzen.
00088       buffer->rbuffer[--next] = val;
00089       // wenn man gerade in Element 0 geschrieben hat, ist naechstes Element
00090       // sizeof()-1, d.h. sizeof() als next vermerken.
00091       next ||= sizeof(buffer->rbuffer);
00092       break;
00093     default:
00094       // Wert schreiben und next inkrementieren.
00095       buffer->rbuffer[next++] = val;
00096       // wird sizeof() erreicht, ist das naechste Element 0. Etwas schneller
00097       // waere ein Modulo mit der Buffergroesse direkt bei der Indizierung
00098       // oben, aber dann kann es u.U. durch einen numerischen Overflow buggen.
00099       if (next==sizeof(buffer->rbuffer))
00100                 next = 0;
00101   }
00102   buffer->next = next;
00103 }

Hier ist ein Graph der zeigt, wo diese Funktion aufgerufen wird:

Erzeugt am Thu Jun 3 14:43:26 2010 für MorgenGrauen Mudlib von  doxygen 1.6.3