1. ホーム
  2. c++

[解決済み] Google Protobufを使ったMap構造の実装方法

2022-02-05 04:54:23

質問

現在、Google protobufを使用していますが、Map構造を利用したいと考えています。しかし、そのようなデータ構造はGoogle protobufに実装されていないことがわかりました。

私の問題は非常に単純です。私は「ページ番号(uint32_t)」と非常にシンプルなコンテンツを持つ構造体を持っています。私が欲しいのは、このページ番号をキーとして使用し、コンテンツを値として使用することです。これなら、スペースとスピードの両方の要求を満たせるはずだ。しかし、Protobufにはそのようなデータ構造はありません。

私が使っている方法は、このようなものです。

message MyPageContent {
    required uint32 contentA = 1;
    required uint32 contentB = 2;
}

message MyTable {
    repeated MyPageContent table= 1;
}

総ページ数はわかっている。そこで、プログラムの最初に、すべてのページコンテンツをテーブルに追加し、特別な値(この値は、ページが存在しないことを通知し、誰もそのコンテンツを使用しないようにするために使用されます。)を追加しました。このようにして、私は暗黙のうちにページ番号をインデックスに使用することができる。ページの準備ができたら、テーブルの中の対応する値を変更する。人々は、コンテンツにアクセスするために、ページ番号をインデックスとして直接使用します。この方法は、多くのスペースを使いますが(多くのページはまだ準備ができていないので、それを知らせるために特別な値をそこに置くだけです。)、アクセスにかかる時間は速いのです。

このようなことを行うための代替方法です。

message MyTable {
    repeated uint32 pageNum = 1;
    repeated MyPageContent myContent = 2;
}

こうすることで、テーブルの準備ができたときにページを追加することができるんだ。このようにして、テーブルの大きさを制限することができるはずです。しかし、人々はまず、そのページがテーブルの中にあるかどうかを探すために線形検索をしなければならない。これでは、多くの時間を消費してしまいます。

基本的にこれが、私がprotobufでMap構造を使いたい理由です。スペースと時間の両方を節約することができます。

どのように解決するのですか?

まさか、(中略)幸いなことに。

Protobufはデータを操作するためのライブラリではなく、シリアライズするためのライブラリです。だから、データを操作するのは std::map などのコンテナを使ってシリアライズし、それを repeated のフィールドをprotobufに格納する。