Ein Ringpuffer, auch zyklischer Puffer genannt, ist eine Datenstruktur, die einen einzigen Puffer fester Größe verwendet, als wären seine Enden miteinander verbunden.
Ein Ringpuffer ist zu Beginn leer und hat eine vorgegebene Länge. Ein Puffer mit 7 Elementen sieht zum Beispiel so aus:
[ ][ ][ ][ ][ ][ ][ ]
Nimm an, dass eine 1 in die Mitte des Puffers geschrieben wird (die genaue Startposition spielt bei einem Ringpuffer keine Rolle):
[ ][ ][ ][1][ ][ ][ ]
Nimm dann an, dass zwei weitere Elemente hinzugefügt werden, 2 und 3, die nach der 1 angehängt werden:
[ ][ ][ ][1][2][3][ ]
Wenn anschließend zwei Elemente aus dem Puffer entfernt werden, werden die ältesten Werte im Puffer entfernt. Die beiden entfernten Elemente sind in diesem Fall 1 und 2, sodass nur eine 3 im Puffer bleibt:
[ ][ ][ ][ ][ ][3][ ]
Wenn der Puffer 7 Elemente enthält, ist er voll:
[5][6][7][8][9][3][4]
Wenn der Puffer voll ist, wird ein Fehler ausgelöst, der den Client darüber informiert, dass weitere Schreibvorgänge blockiert sind, bis ein Platz frei wird.
Wenn der Puffer voll ist, kann der Client die ältesten Daten durch einen erzwungenen Schreibvorgang überschreiben. In diesem Fall werden zwei weitere Elemente hinzugefügt, A und B, und sie überschreiben die 3 und 4:
[5][6][7][8][9][A][B]
3 und 4 wurden durch A und B ersetzt, wodurch 5 jetzt die ältesten Daten im Puffer sind. Wenn schließlich zwei Elemente entfernt werden, werden 5 und 6 zurückgegeben, was den folgenden Puffer ergibt:
[ ][ ][7][8][9][A][B]
Da Platz verfügbar ist, wird, wenn der Client erneut das Überschreiben nutzt, um C und D zu speichern, der Platz verwendet, an dem zuvor 5 und 6 gespeichert waren, und nicht die Position von 7 und 8. 7 ist immer noch das älteste Element, und der Puffer ist wieder voll.
[C][D][7][8][9][A][B]
Diese Übung stellt ein paar Konzepte vor, die du vielleicht noch nie gesehen hast:
Alle Wörter in 8th gehören zu einem Namensraum, z. B. verweist a:new auf das Wort new im Namensraum a.
Man kann auch eigene Namensräume definieren, was wir am Anfang der Datei circular-buffer.8th machen:
ns: cb
Das bedeutet, dass auf alle Wörter in dieser Datei über cb:<word> zugegriffen werden kann, was eine großartige Möglichkeit ist, zusammengehörige Funktionalität zu bündeln.
Weitere Informationen findest du in der Dokumentation zu Namensräumen.
Von den Wörtern read und write wird erwartet, dass sie eine Ausnahme auslösen, wenn sie bei einem Ringpuffer in einem ungültigen Zustand aufgerufen werden.
Weitere Informationen findest du in der Dokumentation zu Ausnahmen und Fehlerbehandlung.
Du kannst den Ringpuffer zwar implementieren, wie du möchtest, aber du könntest die Objektunterstützung von 8th in Betracht ziehen.
Melde dich bei Exercism an, um 8th mit 70 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.
In diesem Video schauen wir uns den Ringpuffer an: was er ist, wo er verwendet wird und welche Implementierungen es gibt – darunter Warteschlangen, statische und dynamische Arrays, unveränderliche Datenstrukturen und eine unterhaltsame agentenbasierte Umsetzung.