固定長データベース
継承クラスとなる固定長クラスの永続化ができたので、これで固定長データベース(Pool)の実装が可能です。
固定長データを扱う場合に、追加するだけなら固定長配列データベースでもあまり問題はないのですが、削除しようとした途端、削除した配列要素の管理が必要になります。まぁ、削除した要素を二度と使わないという手もありますが、そうもいきません。
固定長データベースでは、データを挿入するとデータに割り振られたIDが返り、データを取得したり削除したりするときには、そのIDでデータを指定することとします。
データが削除されるとそのIDはスタック(削除スタック)にプッシュされ、データが挿入されると削除スタックからIDをポップして利用します。削除スタックに何もなければ、固定長配列データベースを拡張するだけです。
template <class T> class Pool { public: Pool() {} Pool(const std::string &f) { initialize(f); } void initialize(const std::string &f) { std::string str = f; str.append("_p"); pool.initialize(str); reservedOffset = pool.reserved(sizeof(size_t)); str = f; str.append("_i"); invalidObjects.initialize(str); } size_t insert() { size_t idx; try { idx = invalidObjects.front(); invalidObjects.pop(); } catch(...) { getPoolSize()++; idx = getPoolSize(); if (idx >= pool.getSize()) { pool.resize(idx + 1); } } return idx; } size_t insert(T &t) { size_t idx = insert(); pool.set(idx - 1, t); return idx; } void remove(size_t idx) { invalidObjects.push(idx); } void set(size_t idx, T &t) { pool.set(idx - 1, t); } T &at(size_t idx) { return pool.at(idx - 1); } protected: Array<T> pool; Stack<size_t> invalidObjects; size_t reservedOffset; size_t &getPoolSize() { return *(size_t*)pool.getReservedVariable(reservedOffset); } };