次のようなインターフェースを定義するSDKに取り組んでいます
class FooIter
{
// Move to the next foo, return false if there is none.
virtual bool Move() = 0;
// Return a pointer to the current foo.
virtual const void* GetFoo() = 0;
// Get the size of a 'foo', which is a fixed-size POD.
virtual size_t GetFooSize() = 0;
// Get a comparator for foos.
virtual const FooComparator* GetComparator() = 0;
};
class FooComparator
{
virtual int compare(const void* first, const void* second) const = 0;
};
基本的に、foo は不透明な型であり、固定長のバイナリ バッファー + および関連する順序付け関数として扱うことができます。
ここで、これらの foo をクライアント コードに戻す前に並べ替えたいと思います。多くのfooが存在する可能性があるため、外部ソートを実装する必要がありますが、std::sort を使用して最初の実行をソートしたいと考えています。
サイズ N * FooIter::GetFooSize() のバッファーを割り当て、FooIter を使用して foos で埋め、ディスクに書き込む前に std::sort で並べ替えると考えていました。
イテレータクラスを書くことから始めることができます
class FooBufferIter
{
public:
FooBufferIter(const void* fooAddr, int fooSize) : m_fooAddr(fooAddr), m_fooSize(fooSize) {}
FooWrapper operator*() {return FooWrapper(m_fooAddr, m_fooSize);}
FooBufferIter operator++() {return FooBufferIter(m_fooAddr + m_fooSize, m_fooSize);}
// All other needed iterator methods.
private:
const void* m_fooAddr;
int m_fooSize;
};
および foo メモリのラッパー クラス
class FooWrapper
{
public:
FooWrapper(const void* fooAddr, int fooSize) : m_fooAddr(fooAddr), m_fooSize(fooSize) {}
private:
const void* m_fooAddr;
int m_fooSize;
};
私の理解では、 std::sort は std::swap を使用してシーケンス内の要素を再配置します。私の問題は、スワップを効率的に実行するために FooWrapper で std::swap を特殊化する方法がわからないことです (最も重要なのは、動的割り当てがないことです)。バイトごとにスワップすることもできますが、それも非効率的です。
これを行う別の方法は、ポインターの並列シーケンスを Foo 配列にソートすることですが、実際には foo は非常に小さい可能性が高いため、並列シーケンスは同じくらい多くを使用できるため、そうしたくありません。メモリを foo シーケンスとして、一度にソートできる数を最大にしたいと考えています。
おそらくこの種のものにより適した古き良きqsortもありますが、FooComparatorオブジェクトを関数ポインターに変換する方法がわかりません(FooComparatorの複数の実装がある可能性があります)。
または、これについてもっと良い方法がありますか?それほど難しくはないかもしれませんが、私は実際には独自のソートの実装を書きたくありません。