FIFO
Andy Valencia
dont at spam.me
Sat May 11 23:44:28 UTC 2024
I need a FIFO for a work scheduler, and nothing suitable jumped
out at me. I wrote the following, but as a newbie, would be
happy to receive any suggestions or observations. TIA!
/*
* fifo.d
* FIFO data structure
*/
module tiny.fifo;
import std.exception : enforce;
const uint GROWBY = 16;
/*
* This is a FIFO, with "hd" walking forward and "tl" trailing
* behind:
* tl hd /Add here next
* v v
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
*
* Mildly complicated by a module-size indexing.
*/
struct FIFO(T) {
T[] items;
ulong hd, tl, length;
void
add(T t) {
// Make more room when needed
if (this.items.length == this.length) {
assert(this.hd == this.tl);
// Add room and shuffle current contents
auto olen = this.items.length;
auto newlen = olen + GROWBY;
this.items.length = newlen;
this.tl = (this.tl + GROWBY) % newlen;
// Shuffle what we're butted up against to their
// new position at the top of this.items[]
ulong moved = olen - this.hd;
this.items[$ - moved .. $] =
this.items[this.hd .. this.hd + moved];
}
// Add item at next position
this.items[hd] = t;
this.hd = (this.hd + 1) % this.items.length;
this.length += 1;
}
// Give back next
T
next() {
enforce(this.length > 0, "next() from empty FIFO");
this.length -= 1;
auto res = this.items[this.tl];
this.tl = (this.tl + 1) % this.items.length;
return res;
}
}
unittest {
auto f = FIFO!uint();
f.add(1);
f.add(2);
f.add(3);
assert(f.next() == 1);
assert(f.next() == 2);
assert(f.next() == 3);
assert(f.length == 0);
// Now overflow several times
f = FIFO!uint();
foreach(x; 0 .. GROWBY * 3 + GROWBY/2) {
f.add(x);
}
foreach(x; 0 .. GROWBY * 3 + GROWBY/2) {
assert(f.next() == x);
}
assert(f.length == 0);
}
version(unittest) {
void
main()
{
}
}
More information about the Digitalmars-d-learn
mailing list