[Issue 2105] Manual Memory Management for Associative Arrays

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Sep 7 16:22:35 PDT 2008


http://d.puremagic.com/issues/show_bug.cgi?id=2105





------- Comment #8 from dsimcha at yahoo.com  2008-09-07 18:22 -------
Here's a possible fix.  A one-line patch that just deletes the old array of
pointers to AA structs when rehashing is needed in aaA.d.  I will attach it. 
Once that is added, the following test case works without memory consumption
going up at all on successive iterations, even with the GC disabled.  I am not
fully confident that this patch doesn't break other stuff, since I don't know
exactly what the Phobos unit tests cover and don't cover, but I did run the
Phobos unit tests with this patch in place and they all passed.

IMHO, especially while GC is partially conservative, it is essential that
builtin types be usable without GC as much as possible.  This certainly seems
feasible in the case of AAs.

import std.gc, std.stdio;

void main () {
    std.gc.disable;
    while(true) {
        test;
        printGCStats;
    }
}

void test() {
    uint[uint] foo;
    for(uint i=0; i < 20_000_000; i++) {
        foo[i]=i;
    }
    deleteAA(foo);
}

void printGCStats() {
    std.gc.GCStats stats;
    std.gc.getStats(stats);
    foreach(s; stats.tupleof)
        write(s, "\t");
    writeln();
}

//These structs are copied and pasted from aaA.d.
struct aaA
{
    aaA *left;
    aaA *right;
    hash_t hash;
    /* key   */
    /* value */
}

struct BB
{
    aaA*[] b;
    size_t nodes;       // total number of aaA nodes
}

struct AA
{
    BB* a;
}

//Could be included in the Phobos runtime
//and called when a delete AA; line is
//encountered.  Might also be called
//automatically if AA is allocated as scope.

void deleteAA(T, U)(T[U] input) {
    auto aaPtr = cast(BB*) cast(void*) input;
    deleteBB(aaPtr);
}

void deleteBB(BB* aaPtr) {

    void rdelAA(aaA* input) {
        if(input.left !is null)
            rdelAA(input.left);
        if(input.right !is null)
            rdelAA(input.right);
        delete input;
    }

    foreach(node; aaPtr.b)
        if(node !is null)
            rdelAA(node);
    delete aaPtr.b;
    delete aaPtr;
}


-- 



More information about the Digitalmars-d-bugs mailing list