title: Multi-valued mappings in Solidity
body: <p>I need to be able to have several possible values under the same key in a mapping. Today, Solidity's mappings are mono-valued: writing a value overwrite the previous one (which is still in the blockchain, but not retrievable by a contract). I wrote this code to have multi-valued mappings:</p>
  
  <pre><code>contract MVM {
  
    struct Bucket {
      bool exists;
      uint num; // Never decreases: we can only add records, not remove them.
      mapping(uint =&gt; Record) records;
    }
  
    struct Record {
      bool exists;
      string info;
    }
  
    // Do not make it public: the compiler crashes when generating
    // accessors https://github.com/ethereum/solidity/issues/633
    mapping(string =&gt; Bucket) data;
  
    function set(string key, string value) {
      if (data[key].exists) {
        data[key].records[data[key].num] = Record(true, value);  
      }
      else {
        data[key].exists = true;
        data[key].records[0] = Record(true, value);
      }
      data[key].num++;
    }
  
    function num_of(string key) returns (uint) {
      return data[key].num; // Guaranteed to be initialized as zero?
    }
  
    function get(string key, uint index) returns (string) {
      if (!data[key].exists || !data[key].records[index].exists) {
        throw;
      }
      return data[key].records[index].info;
    }
  
  }
  </code></pre>
  
  <p>An example of its use from the geth console:</p>
  
  <pre><code> &gt; mvs.set.sendTransaction("foo", "bar", {from:eth.accounts[0], gas: 1000000})
  "0x79c52c437a94f3301775acec5639404eff563fce1a99ad097f5db28f109d7ab5"
  
  &gt; mvm.set.sendTransaction("foo", "thing", {from:eth.accounts[0], gas: 1000000})
  "0xb26b8d34691b0da5cb48af68933e81b514199f4ed8bd2b557767c8b55da85f50"
  &gt; mvm.get.call("foo")
  "bar"
  &gt; mvm.get.call("foo", 1)
  "thing"
  &gt; mvm.num_of.call("foo")
  2
  </code></pre>
  
  <p>Is there a flaw in my approach? Or a better solution?</p>