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()
    {
    }
}
  • FIFO Andy Valencia via Digitalmars-d-learn
    • Re: FIFO Ferhat Kurtulmuş via Digitalmars-d-learn
      • Re: FIFO Andy Valencia via Digitalmars-d-learn
        • Re: FIFO Ferhat Kurtulmuş via Digitalmars-d-learn
          • Re: FIFO Andy Valencia via Digitalmars-d-learn
            • Re: FIFO Salih Dincer via Digitalmars-d-learn
            • Re: FIFO Ferhat Kurtulmuş via Digitalmars-d-learn
            • Re: FIFO Salih Dincer via Digitalmars-d-learn
    • Re: FIFO Ferhat Kurtulmuş via Digitalmars-d-learn
    • Re: FIFO Ferhat Kurtulmuş via Digitalmars-d-learn

Reply via email to