#include <mtbl.h>
#include <memory>
#include <string>
+#include <unordered_set>
#include <string.h>
#include <assert.h>
-#include "count.h"
+#include "count.pb.h"
using namespace std;
-
void merge_count(void* userdata,
const uint8_t *key, size_t len_key,
const uint8_t *val0, size_t len_val0,
const uint8_t *val1, size_t len_val1,
uint8_t **merged_val, size_t *len_merged_val)
{
- assert(len_val0 == sizeof(Count));
- assert(len_val1 == sizeof(Count));
-
- const Count* c0 = reinterpret_cast<const Count*>(val0);
- const Count* c1 = reinterpret_cast<const Count*>(val1);
- unique_ptr<Count> c((Count *)malloc(sizeof(Count))); // Needs to be with malloc, per merger spec.
-
- c->white = c0->white + c1->white;
- c->draw = c0->draw + c1->draw;
- c->black = c0->black + c1->black;
- c->opening_num = c0->opening_num; // Arbitrary choice.
- c->sum_white_elo = c0->sum_white_elo + c1->sum_white_elo;
- c->sum_black_elo = c0->sum_black_elo + c1->sum_black_elo;
- c->num_elo = c0->num_elo + c1->num_elo;
-
- *merged_val = reinterpret_cast<uint8_t *>(c.release());
- *len_merged_val = sizeof(Count);
+ Count c0, c1;
+ c0.ParseFromArray(val0, len_val0);
+ c1.ParseFromArray(val1, len_val1);
+
+ Count c;
+
+ c.set_white(c0.white() + c1.white());
+ c.set_draw(c0.draw() + c1.draw());
+ c.set_black(c0.black() + c1.black());
+ c.set_sum_white_elo(c0.sum_white_elo() + c1.sum_white_elo());
+ c.set_sum_black_elo(c0.sum_black_elo() + c1.sum_black_elo());
+ c.set_num_elo(c0.num_elo() + c1.num_elo());
+ if (c0.first_timestamp() <= c1.first_timestamp()) {
+ c.set_opening_num(c0.opening_num());
+ if (c0.has_first_timestamp()) {
+ c.set_first_timestamp(c0.first_timestamp());
+ }
+ c.set_pgn_file_num(c0.pgn_file_num());
+ c.set_pgn_start_position(c0.pgn_start_position());
+ } else {
+ c.set_opening_num(c1.opening_num());
+ if (c1.has_first_timestamp()) {
+ c.set_first_timestamp(c1.first_timestamp());
+ }
+ c.set_pgn_file_num(c1.pgn_file_num());
+ c.set_pgn_start_position(c1.pgn_start_position());
+ }
+
+ // Merge the moves, with deduplication.
+ unordered_set<string> moves;
+ for (int i = 0; i < c0.move_size(); ++i) {
+ moves.insert(c0.move(i));
+ c.add_move(c0.move(i));
+ }
+ for (int i = 0; i < c1.move_size(); ++i) {
+ if (!moves.count(c1.move(i))) {
+ c.add_move(c1.move(i));
+ }
+ }
+
+ static string buf; // Keep allocated.
+ c.SerializeToString(&buf);
+
+ *merged_val = reinterpret_cast<uint8_t *>(malloc(buf.size()));
+ *len_merged_val = buf.size();
+ memcpy(*merged_val, buf.data(), buf.size());
}
int main(int argc, char **argv)
mtbl_merger_add_source(merger, mtbl_reader_source(mtbl));
}
- mtbl_writer* writer = mtbl_writer_init(argv[argc - 1], NULL);
+ mtbl_writer_options* wopt = mtbl_writer_options_init();
+ mtbl_writer_options_set_block_size(wopt, 65536);
+ mtbl_writer* writer = mtbl_writer_init(argv[argc - 1], wopt);
mtbl_source_write(mtbl_merger_source(merger), writer);
mtbl_writer_destroy(&writer);
}