file i/o in a variety of languages

bearophile bearophileHUGS at lycos.com
Fri Aug 27 17:03:41 PDT 2010


Andrei:
> The open() method saves on reallocating the refcounted
> structured stored inside the File.

Thank you for your answer.
So the API is designed a bit larger than necessary for performance reasons.

This the reformatted first part of the interesting implementation of File:


struct File {
    private struct Impl {
        FILE* handle = null;
        uint refs = uint.max / 2;
        string name = null;

        this(FILE* h, uint r, string n) {
            handle = h;
            refs = r;
            name = n;
        }
    }
    private Impl* p;

    this(string name, in char[] stdioOpenmode="rb") {
        p = new Impl(errnoEnforce(.fopen(name, stdioOpenmode),
                                  text("Cannot open file `", name, "' in mode `", stdioOpenmode, "'")),
                     1,
                     name);
    }

    ~this() {
        if (!p)
            return;
        if (p.refs == 1)
            close;
        else
            --p.refs;
    }

    this(this) {
        if (!p)
            return;
        assert(p.refs);
        ++p.refs;
    }

    void opAssign(File rhs) {
        swap(p, rhs.p);
    }
    
    void open(string name, in char[] stdioOpenmode="rb") {
        detach;
        auto another = File(name, stdioOpenmode);
        swap(this, another);
    }


Few comments:

I am slowly starting to understand the purpose of that Impl :-) It allows to use File as as a class instance, as it is by reference.


According to D specs on the site, inner structs contain an extra scope pointer, so this may be better:
private static struct Impl {
I have seen the same problem in other parts of Phobos (see bug http://d.puremagic.com/issues/show_bug.cgi?id=4087 ).


open() contains:
auto another = File(name, stdioOpenmode);
That calls File.this(), so isn't it creating a new Impl anyway? I don't understand the performance gain still.


Given the presence of opAssign, I presume this code:
auto another = File(name, stdioOpenmode);
swap(this, another);
May be written just as:
this = File(name, stdioOpenmode);

Bye and thank you,
bearophile


More information about the Digitalmars-d mailing list