Stable HashMap without need for an upgrade func

Happy new year, Guys.

I ‘d like to discuss about StableHashMap that simplify upgrade steps.

When we use HashMap lib in Motoko, we have to implement these code. Because class variables can not be stable.

    var hp = HashMap.HashMap<Text, Nat>(1, Text.equal, Text.hash);
    stable var entries : [(Text, Nat)] = [];

    system func preupgrade() {
        entries := Iter.toArray(hp.entries());
    };

    system func postupgrade() {
        hp := HashMap.fromIter<Text, Nat>(entries.vals(), 1, Text.equal, Text.hash);
        entries := [];
    };

This way is difficult to understand and tend to make mistakes.

So, I thought much simpler way to upgrade HashMap.

    var hp = HashMap.HashMap<Text, Nat>(1, Text.equal, Text.hash);
    stable var stableVars = hp.exportVars();

    system func preupgrade() {
        stableVars := hp.exportVars();
    };
    system func postupgrade() {
        hp := HashMap.HashMap<Text, Nat>(1, Text.equal, Text.hash);
        hp.importVars(stableVars);
    };


This is implemented by passing the address of table variable inside HashMap class object to the stable variable in main.

If it is possible to share stable name space, we don’t need upgrade methods anymore.
But now, stable variables are bound in compiler, not address. So they can’t pass stable as an argument either.

By changing Motoko’s syntax and allowing stable var namespaces to be shared, we will be released from the hassle of the upgrade method.

Here is a proof of concept.
// GitHub URL

Thanks.

2 Likes