0

我有以下问题:一个值,可以与两个不同的键相关联。例子:

  • uint64 key1 -> 值
  • uint32 key2 -> 值

所以查询可以是双重的:

table.find(uint64 key1) 或
table.find(uint32 key2)

key1 和 key2 是完全独立的。是否有可能实现一个通过两个键访问而不复制项目的表?

一种可能的解决方案(psedocode):

class TwoKeyHashTable {
  Value find(uint64);
  Value find(uint32);

  insert(key1, key2, value) {
    insert_into_table(key1, value);
    insert_into_table(key2, value);
  }

  struct Item {
    uint64 key1;
    uint32 key2;
    Value value;
  } *table;
};

但是,此解决方案使表中的项目数量增加了一倍。我有数亿个项目,我想将整个表保存在内存中,所以我问是否存在更高效的内存?

4

1 回答 1

1

哇,我很惊讶周围没有任何想法...... :-/ 所以我实现了表格,复制了所有项目,如下所示:

class TwoKeysHashTable {
 public:
  struct Item {
    uint64 key1;
    uint32 key2;
    int32 value;

    Item() : key1(0), key2(0) { }

    Item(uint64 k1, uint32 k2, int val)
       : key1(k1), key2(k2), value(val) { }
  };

  ...

  Item *Find(uint64 key) const;
  Item *Find(uint32 key) const;
  int Insert(uint64 key1, uint32 key2, int value);

 private:
  Item *FindKey1(uint64 key, int *return_index) const;
  Item *FindKey2(uint32 key, int *return_index) const;

  int GetNextIndex(int start_index, int counter) const;
  void Rehash();

  Item *array_;
  int number_key1_;
  int number_key2_;
  int allocated_items_;
};

为了不复制(真实)数据,它存储在一个压缩数组中,'Item::value' 是该数组的索引。“Insert”调用“FindKey1”和“FindKey2”来查询表中是否已经存在键,如果没有,则将在返回的索引处插入新的项。我使用开放散列来保持数组尽可能紧凑。尽管付出了所有努力,该表仍在为我的数据使用超过 8GB 的​​内存(而且我没有计算实际数据,“值”指向)。

任何想法如何更有效地做到这一点?谢谢...

于 2013-08-28T03:54:58.523 回答