From 142233018d154a8d729344f24baa4bf98fa6a006 Mon Sep 17 00:00:00 2001 From: lynncui00 Date: Wed, 22 Jun 2016 03:25:50 +0800 Subject: [PATCH] version 0.9 --- AUTHORS | 11 + INSTALL | 93 + LICENSE | 215 + MANIFEST | 204 + Makefile.define | 31 + README | 4 + autoinstall.sh | 97 + include/Makefile.define | 31 + include/phxpaxos/breakpoint.h | 246 + include/phxpaxos/def.h | 55 + include/phxpaxos/log.h | 40 + include/phxpaxos/network.h | 60 + include/phxpaxos/node.h | 108 + include/phxpaxos/options.h | 187 + include/phxpaxos/sm.h | 103 + include/phxpaxos/storage.h | 71 + license.py | 41 + makefile.mk | 127 + plugin/Makefile.define | 31 + plugin/include/Makefile.define | 31 + .../include/phxpaxos_plugin/logger_google.h | 52 + plugin/include/phxpaxos_plugin/monitor.h | 46 + plugin/logger_google/Makefile.define | 31 + plugin/logger_google/logger_google.cpp | 116 + plugin/logger_google/logger_google_impl.cpp | 111 + plugin/logger_google/logger_google_impl.h | 46 + plugin/monitor/Makefile.define | 31 + plugin/monitor/monitor.cpp | 45 + plugin/monitor/monitor_bp.cpp | 732 +++ plugin/monitor/monitor_bp.h | 297 + sample/phxecho/Makefile.define | 31 + sample/phxecho/README | 9 + sample/phxecho/echo_server.cpp | 139 + sample/phxecho/echo_server.h | 56 + sample/phxecho/echo_sm.cpp | 51 + sample/phxecho/echo_sm.h | 55 + sample/phxecho/main.cpp | 134 + sample/phxecho/run_echo.sh | 4 + sample/phxelection/Makefile.define | 31 + sample/phxelection/README | 2 + sample/phxelection/election.cpp | 113 + sample/phxelection/election.h | 56 + sample/phxelection/election_main.cpp | 124 + sample/phxelection/run_election_sample.sh | 4 + sample/phxkv/Makefile.define | 51 + sample/phxkv/README | 9 + sample/phxkv/client_tools_sample.sh | 14 + sample/phxkv/def.h | 49 + sample/phxkv/kv.cpp | 279 + sample/phxkv/kv.h | 67 + sample/phxkv/kv_grpc_client.cpp | 231 + sample/phxkv/kv_grpc_client.h | 76 + sample/phxkv/kv_grpc_client_main.cpp | 172 + sample/phxkv/kv_grpc_server.cpp | 127 + sample/phxkv/kv_grpc_server.h | 51 + sample/phxkv/kv_grpc_server_main.cpp | 148 + sample/phxkv/kv_paxos.cpp | 226 + sample/phxkv/kv_paxos.h | 81 + sample/phxkv/kvsm.cpp | 201 + sample/phxkv/kvsm.h | 116 + sample/phxkv/log.cpp | 63 + sample/phxkv/log.h | 65 + sample/phxkv/phxkv.grpc.pb.cc | 126 + sample/phxkv/phxkv.grpc.pb.h | 251 + sample/phxkv/phxkv.pb.cc | 1446 +++++ sample/phxkv/phxkv.pb.h | 643 +++ sample/phxkv/phxkv.proto | 33 + sample/phxkv/prepare_dir.sh | 13 + sample/phxkv/run_server_sample.sh | 4 + sample/phxkv/utils.cpp | 63 + sample/phxkv/utils.h | 130 + src/algorithm/Makefile.define | 31 + src/algorithm/acceptor.cpp | 336 ++ src/algorithm/acceptor.h | 90 + src/algorithm/base.cpp | 300 + src/algorithm/base.h | 168 + src/algorithm/checkpoint_receiver.cpp | 270 + src/algorithm/checkpoint_receiver.h | 72 + src/algorithm/checkpoint_sender.cpp | 384 ++ src/algorithm/checkpoint_sender.h | 102 + src/algorithm/commitctx.cpp | 165 + src/algorithm/commitctx.h | 73 + src/algorithm/committer.cpp | 145 + src/algorithm/committer.h | 64 + src/algorithm/instance.cpp | 753 +++ src/algorithm/instance.h | 140 + src/algorithm/ioloop.cpp | 255 + src/algorithm/ioloop.h | 82 + src/algorithm/learner.cpp | 922 +++ src/algorithm/learner.h | 218 + src/algorithm/learner_sender.cpp | 263 + src/algorithm/learner_sender.h | 87 + src/algorithm/msg_counter.cpp | 86 + src/algorithm/msg_counter.h | 58 + src/algorithm/proposer.cpp | 502 ++ src/algorithm/proposer.h | 142 + src/benchmark/HOW_TO_BENCH | 35 + src/benchmark/Makefile.define | 31 + src/benchmark/bench_main.cpp | 265 + src/benchmark/bench_server.cpp | 157 + src/benchmark/bench_server.h | 61 + src/benchmark/bench_sm.cpp | 47 + src/benchmark/bench_sm.h | 70 + src/benchmark/fsync_bench.cpp | 126 + src/checkpoint/Makefile.define | 31 + src/checkpoint/cleaner.cpp | 203 + src/checkpoint/cleaner.h | 84 + src/checkpoint/cp_mgr.cpp | 184 + src/checkpoint/cp_mgr.h | 92 + src/checkpoint/replayer.cpp | 136 + src/checkpoint/replayer.h | 70 + src/comm/Makefile.define | 31 + src/comm/breakpoint.cpp | 100 + src/comm/comm_include.h | 26 + src/comm/commdef.h | 125 + src/comm/inside_options.cpp | 238 + src/comm/inside_options.h | 93 + src/comm/logger.cpp | 174 + src/comm/logger.h | 67 + src/comm/msg_transport.h | 53 + src/comm/options.cpp | 132 + src/comm/paxos_msg.pb.cc | 4992 +++++++++++++++++ src/comm/paxos_msg.pb.h | 2413 ++++++++ src/comm/paxos_msg.proto | 77 + src/communicate/Makefile.define | 31 + src/communicate/communicate.cpp | 127 + src/communicate/communicate.h | 69 + src/communicate/dfnetwork.cpp | 86 + src/communicate/dfnetwork.h | 54 + src/communicate/network.cpp | 48 + src/communicate/tcp/Makefile.define | 31 + src/communicate/tcp/event_base.cpp | 112 + src/communicate/tcp/event_base.h | 72 + src/communicate/tcp/event_loop.cpp | 335 ++ src/communicate/tcp/event_loop.h | 97 + src/communicate/tcp/message_event.cpp | 462 ++ src/communicate/tcp/message_event.h | 122 + src/communicate/tcp/notify.cpp | 91 + src/communicate/tcp/notify.h | 55 + src/communicate/tcp/tcp.cpp | 72 + src/communicate/tcp/tcp.h | 52 + src/communicate/tcp/tcp_acceptor.cpp | 167 + src/communicate/tcp/tcp_acceptor.h | 70 + src/communicate/tcp/tcp_client.cpp | 106 + src/communicate/tcp/tcp_client.h | 63 + src/communicate/udp.cpp | 221 + src/communicate/udp.h | 79 + src/config/Makefile.define | 31 + src/config/config.cpp | 253 + src/config/config.h | 120 + src/config/config_include.h | 26 + src/config/inside_sm.h | 40 + src/config/system_v_sm.cpp | 366 ++ src/config/system_v_sm.h | 118 + src/logstorage/Makefile.define | 31 + src/logstorage/db.cpp | 778 +++ src/logstorage/db.h | 165 + src/logstorage/log_store.cpp | 551 ++ src/logstorage/log_store.h | 94 + src/logstorage/paxos_log.cpp | 155 + src/logstorage/paxos_log.h | 53 + src/logstorage/system_variables_store.cpp | 87 + src/logstorage/system_variables_store.h | 47 + src/master/Makefile.define | 31 + src/master/master_damon.cpp | 163 + src/master/master_damon.h | 71 + src/master/master_sm.cpp | 315 ++ src/master/master_sm.h | 129 + src/master/master_sm.pb.cc | 673 +++ src/master/master_sm.pb.h | 309 + src/master/master_sm.proto | 12 + src/master/master_variables_store.cpp | 87 + src/master/master_variables_store.h | 47 + src/node/Makefile.define | 31 + src/node/group.cpp | 91 + src/node/group.h | 66 + src/node/node.cpp | 64 + src/node/pnode.cpp | 452 ++ src/node/pnode.h | 112 + src/sm-base/Makefile.define | 31 + src/sm-base/sm.cpp | 69 + src/sm-base/sm_base.cpp | 200 + src/sm-base/sm_base.h | 61 + src/test/Makefile.define | 31 + src/test/test_main.cpp | 369 ++ src/test/test_server.cpp | 138 + src/test/test_server.h | 60 + src/test/test_sm.cpp | 82 + src/test/test_sm.h | 50 + src/tools/Makefile.define | 41 + src/tools/paxos_log_tools.cpp | 96 + src/tools/run_svm_tools.sh | 1 + src/tools/system_variables_tools.cpp | 118 + src/ut/Makefile.define | 31 + src/ut/acceptor_ut.cpp | 298 + src/ut/db_ut.cpp | 227 + src/ut/make_class.cpp | 100 + src/ut/make_class.h | 46 + src/ut/mock_class.h | 110 + src/ut/nodeid_ut.cpp | 55 + src/ut/proposer_ut.cpp | 300 + src/ut/timer_ut.cpp | 117 + src/ut/ut_main.cpp | 28 + src/ut/wait_lock_ut.cpp | 131 + src/utils/Makefile.define | 31 + src/utils/bytes_buffer.cpp | 71 + src/utils/bytes_buffer.h | 44 + src/utils/concurrent.cpp | 220 + src/utils/concurrent.h | 359 ++ src/utils/crc32.cpp | 90 + src/utils/crc32.h | 29 + src/utils/serial_lock.cpp | 68 + src/utils/serial_lock.h | 48 + src/utils/socket.cpp | 580 ++ src/utils/socket.h | 230 + src/utils/timer.cpp | 94 + src/utils/timer.h | 72 + src/utils/util.cpp | 282 + src/utils/util.h | 125 + src/utils/utils_include.h | 31 + src/utils/wait_lock.cpp | 80 + src/utils/wait_lock.h | 44 + src_list | 1 + tools/build_comm.py | 15 + tools/build_comm.pyc | Bin 0 -> 862 bytes tools/check_install.py | 70 + tools/create_makefile.py | 323 ++ 227 files changed, 38545 insertions(+) create mode 100644 AUTHORS create mode 100644 INSTALL create mode 100644 LICENSE create mode 100644 MANIFEST create mode 100644 Makefile.define create mode 100644 README create mode 100755 autoinstall.sh create mode 100644 include/Makefile.define create mode 100644 include/phxpaxos/breakpoint.h create mode 100644 include/phxpaxos/def.h create mode 100644 include/phxpaxos/log.h create mode 100644 include/phxpaxos/network.h create mode 100644 include/phxpaxos/node.h create mode 100644 include/phxpaxos/options.h create mode 100644 include/phxpaxos/sm.h create mode 100644 include/phxpaxos/storage.h create mode 100644 license.py create mode 100644 makefile.mk create mode 100644 plugin/Makefile.define create mode 100644 plugin/include/Makefile.define create mode 100644 plugin/include/phxpaxos_plugin/logger_google.h create mode 100644 plugin/include/phxpaxos_plugin/monitor.h create mode 100644 plugin/logger_google/Makefile.define create mode 100644 plugin/logger_google/logger_google.cpp create mode 100644 plugin/logger_google/logger_google_impl.cpp create mode 100644 plugin/logger_google/logger_google_impl.h create mode 100644 plugin/monitor/Makefile.define create mode 100644 plugin/monitor/monitor.cpp create mode 100644 plugin/monitor/monitor_bp.cpp create mode 100644 plugin/monitor/monitor_bp.h create mode 100644 sample/phxecho/Makefile.define create mode 100644 sample/phxecho/README create mode 100644 sample/phxecho/echo_server.cpp create mode 100644 sample/phxecho/echo_server.h create mode 100644 sample/phxecho/echo_sm.cpp create mode 100644 sample/phxecho/echo_sm.h create mode 100644 sample/phxecho/main.cpp create mode 100644 sample/phxecho/run_echo.sh create mode 100644 sample/phxelection/Makefile.define create mode 100644 sample/phxelection/README create mode 100644 sample/phxelection/election.cpp create mode 100644 sample/phxelection/election.h create mode 100644 sample/phxelection/election_main.cpp create mode 100644 sample/phxelection/run_election_sample.sh create mode 100644 sample/phxkv/Makefile.define create mode 100644 sample/phxkv/README create mode 100644 sample/phxkv/client_tools_sample.sh create mode 100644 sample/phxkv/def.h create mode 100644 sample/phxkv/kv.cpp create mode 100644 sample/phxkv/kv.h create mode 100644 sample/phxkv/kv_grpc_client.cpp create mode 100644 sample/phxkv/kv_grpc_client.h create mode 100644 sample/phxkv/kv_grpc_client_main.cpp create mode 100644 sample/phxkv/kv_grpc_server.cpp create mode 100644 sample/phxkv/kv_grpc_server.h create mode 100644 sample/phxkv/kv_grpc_server_main.cpp create mode 100644 sample/phxkv/kv_paxos.cpp create mode 100644 sample/phxkv/kv_paxos.h create mode 100644 sample/phxkv/kvsm.cpp create mode 100644 sample/phxkv/kvsm.h create mode 100644 sample/phxkv/log.cpp create mode 100644 sample/phxkv/log.h create mode 100644 sample/phxkv/phxkv.grpc.pb.cc create mode 100644 sample/phxkv/phxkv.grpc.pb.h create mode 100644 sample/phxkv/phxkv.pb.cc create mode 100644 sample/phxkv/phxkv.pb.h create mode 100644 sample/phxkv/phxkv.proto create mode 100644 sample/phxkv/prepare_dir.sh create mode 100644 sample/phxkv/run_server_sample.sh create mode 100644 sample/phxkv/utils.cpp create mode 100644 sample/phxkv/utils.h create mode 100644 src/algorithm/Makefile.define create mode 100644 src/algorithm/acceptor.cpp create mode 100644 src/algorithm/acceptor.h create mode 100644 src/algorithm/base.cpp create mode 100644 src/algorithm/base.h create mode 100644 src/algorithm/checkpoint_receiver.cpp create mode 100644 src/algorithm/checkpoint_receiver.h create mode 100644 src/algorithm/checkpoint_sender.cpp create mode 100644 src/algorithm/checkpoint_sender.h create mode 100644 src/algorithm/commitctx.cpp create mode 100644 src/algorithm/commitctx.h create mode 100644 src/algorithm/committer.cpp create mode 100644 src/algorithm/committer.h create mode 100644 src/algorithm/instance.cpp create mode 100644 src/algorithm/instance.h create mode 100644 src/algorithm/ioloop.cpp create mode 100644 src/algorithm/ioloop.h create mode 100644 src/algorithm/learner.cpp create mode 100644 src/algorithm/learner.h create mode 100644 src/algorithm/learner_sender.cpp create mode 100644 src/algorithm/learner_sender.h create mode 100644 src/algorithm/msg_counter.cpp create mode 100644 src/algorithm/msg_counter.h create mode 100644 src/algorithm/proposer.cpp create mode 100644 src/algorithm/proposer.h create mode 100644 src/benchmark/HOW_TO_BENCH create mode 100644 src/benchmark/Makefile.define create mode 100644 src/benchmark/bench_main.cpp create mode 100644 src/benchmark/bench_server.cpp create mode 100644 src/benchmark/bench_server.h create mode 100644 src/benchmark/bench_sm.cpp create mode 100644 src/benchmark/bench_sm.h create mode 100644 src/benchmark/fsync_bench.cpp create mode 100644 src/checkpoint/Makefile.define create mode 100644 src/checkpoint/cleaner.cpp create mode 100644 src/checkpoint/cleaner.h create mode 100644 src/checkpoint/cp_mgr.cpp create mode 100644 src/checkpoint/cp_mgr.h create mode 100644 src/checkpoint/replayer.cpp create mode 100644 src/checkpoint/replayer.h create mode 100644 src/comm/Makefile.define create mode 100644 src/comm/breakpoint.cpp create mode 100644 src/comm/comm_include.h create mode 100644 src/comm/commdef.h create mode 100644 src/comm/inside_options.cpp create mode 100644 src/comm/inside_options.h create mode 100644 src/comm/logger.cpp create mode 100644 src/comm/logger.h create mode 100644 src/comm/msg_transport.h create mode 100644 src/comm/options.cpp create mode 100644 src/comm/paxos_msg.pb.cc create mode 100644 src/comm/paxos_msg.pb.h create mode 100644 src/comm/paxos_msg.proto create mode 100644 src/communicate/Makefile.define create mode 100644 src/communicate/communicate.cpp create mode 100644 src/communicate/communicate.h create mode 100644 src/communicate/dfnetwork.cpp create mode 100644 src/communicate/dfnetwork.h create mode 100644 src/communicate/network.cpp create mode 100644 src/communicate/tcp/Makefile.define create mode 100644 src/communicate/tcp/event_base.cpp create mode 100644 src/communicate/tcp/event_base.h create mode 100644 src/communicate/tcp/event_loop.cpp create mode 100644 src/communicate/tcp/event_loop.h create mode 100644 src/communicate/tcp/message_event.cpp create mode 100644 src/communicate/tcp/message_event.h create mode 100644 src/communicate/tcp/notify.cpp create mode 100644 src/communicate/tcp/notify.h create mode 100644 src/communicate/tcp/tcp.cpp create mode 100644 src/communicate/tcp/tcp.h create mode 100644 src/communicate/tcp/tcp_acceptor.cpp create mode 100644 src/communicate/tcp/tcp_acceptor.h create mode 100644 src/communicate/tcp/tcp_client.cpp create mode 100644 src/communicate/tcp/tcp_client.h create mode 100644 src/communicate/udp.cpp create mode 100644 src/communicate/udp.h create mode 100644 src/config/Makefile.define create mode 100644 src/config/config.cpp create mode 100644 src/config/config.h create mode 100644 src/config/config_include.h create mode 100644 src/config/inside_sm.h create mode 100644 src/config/system_v_sm.cpp create mode 100644 src/config/system_v_sm.h create mode 100644 src/logstorage/Makefile.define create mode 100644 src/logstorage/db.cpp create mode 100644 src/logstorage/db.h create mode 100644 src/logstorage/log_store.cpp create mode 100644 src/logstorage/log_store.h create mode 100644 src/logstorage/paxos_log.cpp create mode 100644 src/logstorage/paxos_log.h create mode 100644 src/logstorage/system_variables_store.cpp create mode 100644 src/logstorage/system_variables_store.h create mode 100644 src/master/Makefile.define create mode 100644 src/master/master_damon.cpp create mode 100644 src/master/master_damon.h create mode 100644 src/master/master_sm.cpp create mode 100644 src/master/master_sm.h create mode 100644 src/master/master_sm.pb.cc create mode 100644 src/master/master_sm.pb.h create mode 100644 src/master/master_sm.proto create mode 100644 src/master/master_variables_store.cpp create mode 100644 src/master/master_variables_store.h create mode 100644 src/node/Makefile.define create mode 100644 src/node/group.cpp create mode 100644 src/node/group.h create mode 100644 src/node/node.cpp create mode 100644 src/node/pnode.cpp create mode 100644 src/node/pnode.h create mode 100644 src/sm-base/Makefile.define create mode 100644 src/sm-base/sm.cpp create mode 100644 src/sm-base/sm_base.cpp create mode 100644 src/sm-base/sm_base.h create mode 100644 src/test/Makefile.define create mode 100644 src/test/test_main.cpp create mode 100644 src/test/test_server.cpp create mode 100644 src/test/test_server.h create mode 100644 src/test/test_sm.cpp create mode 100644 src/test/test_sm.h create mode 100644 src/tools/Makefile.define create mode 100644 src/tools/paxos_log_tools.cpp create mode 100644 src/tools/run_svm_tools.sh create mode 100644 src/tools/system_variables_tools.cpp create mode 100644 src/ut/Makefile.define create mode 100644 src/ut/acceptor_ut.cpp create mode 100644 src/ut/db_ut.cpp create mode 100644 src/ut/make_class.cpp create mode 100644 src/ut/make_class.h create mode 100644 src/ut/mock_class.h create mode 100644 src/ut/nodeid_ut.cpp create mode 100644 src/ut/proposer_ut.cpp create mode 100644 src/ut/timer_ut.cpp create mode 100644 src/ut/ut_main.cpp create mode 100644 src/ut/wait_lock_ut.cpp create mode 100644 src/utils/Makefile.define create mode 100644 src/utils/bytes_buffer.cpp create mode 100644 src/utils/bytes_buffer.h create mode 100644 src/utils/concurrent.cpp create mode 100644 src/utils/concurrent.h create mode 100644 src/utils/crc32.cpp create mode 100644 src/utils/crc32.h create mode 100644 src/utils/serial_lock.cpp create mode 100644 src/utils/serial_lock.h create mode 100644 src/utils/socket.cpp create mode 100644 src/utils/socket.h create mode 100644 src/utils/timer.cpp create mode 100644 src/utils/timer.h create mode 100644 src/utils/util.cpp create mode 100644 src/utils/util.h create mode 100644 src/utils/utils_include.h create mode 100644 src/utils/wait_lock.cpp create mode 100644 src/utils/wait_lock.h create mode 100644 src_list create mode 100644 tools/build_comm.py create mode 100644 tools/build_comm.pyc create mode 100644 tools/check_install.py create mode 100644 tools/create_makefile.py diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..936b328b9 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,11 @@ +# Names should be added to this file like so: +# Name or Organization + +Tencent Inc. + +Sifan Liu +Ming Chen +Haochuan Cui +Duokai Huang +Junechao Chen + diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..21683671a --- /dev/null +++ b/INSTALL @@ -0,0 +1,93 @@ +Installation Instructions +************************* + +Copyright (C) 2016 Tencent. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +PhxPaxos-Specific Installation Notes +==================================== + +*** NOTE FOR 64-BIT LINUX SYSTEMS + +The PhxPaxos library has to be built on 64-bit systems or you may +experience some problems. + +Basic Installation +================== + +Briefly, the shell commands `sh autoinstall.sh; make;' should configure +and build this package. The following more-detailed instructions are +generic; see the `README' file for instructions specific to this package. + + The `autoinstall.sh' shell script attempts to guess correct values +for various system-dependent variables used during compilation. It +uses those values and Makefile.define in each directory which describes +the source files infomation to create a `Makefile' in each directory of +the package. + + The file `makefile.mk' is used to set options of the compilation +environment. You need modify it if you want to change the options including +the paths of the third party libraries, like glog, leveldb, and protobuf. + + The grpc library is required if you want to complile the example +source. + +The simplest way to compile this package is: + 1. Make sure the third party libraries, protobuf (3.0 or above) and + leveldb, have been installed in the system. If you want to test the + samples, libraries of glog and grpc are also required. + + 2. `cd' to the directory containing the package's source code and type + `sh autoinstall.sh' to configure the package for your system. + + 3. Type `make' to compile the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the source + code directory by typing `make clean'. + +Compilers and Options +===================== + +Glibc 2.12 or above, as well as 64bit option and C++ 11 support in compiler, +is required to build the library. + +If you want to include more options, modifying the makefile.mk file in +the source code directory is a good idea. + +Installation Position--------------TODO +===================== + +Libraries are under ./lib and include files are under ./include, related to +the local source code directory. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`./lib', include files under `./include', etc. You +can specify an installation prefix by giving `autointall.sh' the option +`--prefix=PREFIX'. + +Installation Plugin +============== + +Usage of Plugin can be found in plugin directory + +The simplest way to compile this plugin is: + + 1. `cd plugin' to the plugin directory containing the plugin library's + source code. + + 2. Type `make' to compile the plugin. + + 3. Type `make install' to install the programs and any data files and + documentation. + + 4. You can remove the program binaries and object files from the source + code directory by typing `make clean'. + diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..485bdac21 --- /dev/null +++ b/LICENSE @@ -0,0 +1,215 @@ +Tencent is pleased to support the open source community by making +PhxPaxos available. + +See the AUTHORS file for names of contributors. + +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. +If you have downloaded a copy of the PhxPaxos binary from Tencent, +please note that the PhxPaxos binary is licensed under +the BSD 3-Clause License. +If you have downloaded a copy of the PhxPaxos source code from +Tencent, please note that PhxPaxos source code is licensed under +the BSD 3-Clause License, except for the third-party components +listed below which are subject to different license terms. Your +integration of PhxPaxos into your own projects may require +compliance with the BSD 3-Clause License, as well as the other +licenses applicable to the third-party components included within +PhxPaxos. + +A copy of the BSD 3-Clause License is included in this file. +Other dependencies and licenses: + +Open Source Software Licensed under the OpenSSL License: +------------------------------------------------------------------ +1. OpenSSL 1.0.2h +Copyright (c) 1998-2016 The OpenSSL Project. +All rights reserved. +Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +All rights reserved. + + +Terms of the OpenSSL License: +------------------------------------------------------------------ + +OpenSSL +The OpenSSL toolkit stays under a dual license, i.e. both the +conditions of the OpenSSL License and the original SSLeay license +apply to the toolkit. The contents of this file are subject to +OpenSSL License; you may not use this file except in compliance +with the License. You may obtain a copy of the License at +http://www.openssl.org/source/license.html + +Copyright (c) 1998-2016 The OpenSSL Project. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. All advertising materials mentioning features or use of this +software must display the following acknowledgment: +"This product includes software developed by the OpenSSL Project +for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + +4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be +used to endorse or promote products derived from this software +without prior written permission. For written permission, please +contact openssl-core@openssl.org. + +5. Products derived from this software may not be called "OpenSSL" +nor may "OpenSSL" appear in their names without prior written +permission of the OpenSSL Project. + +6. Redistributions of any form whatsoever must retain the following +acknowledgment: +"This product includes software developed by the OpenSSL Project +for use in the OpenSSL Toolkit (http://www.openssl.org/)" + +THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +* This product includes cryptographic software written by Eric Young +(eay@cryptsoft.com). This product includes software written by +Tim Hudson (tjh@cryptsoft.com). + +==================================================================== + +The contents of this file are subject to SSLeay License; you may not +use this file except in compliance with the License. You may obtain +a copy of the License at + +http://www.openssl.org/source/license.html +Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +All rights reserved. + +This package is an SSL implementation written by Eric Young +(eay@cryptsoft.com). +The implementation was written so as to conform with Netscapes SSL. +This library is free for commercial and non-commercial use as long +as the following conditions are aheared to. The following conditions +apply to all code found in this distribution, be it the RC4, RSA, +lhash, DES, etc., code; not just the SSL code. The SSL documentation +included with this distribution is covered by the same copyright +terms except that the holder is Tim Hudson (tjh@cryptsoft.com). +Copyright remains Eric Young's, and as such any Copyright notices +in the code are not to be removed. If this package is used in a +product, Eric Young should be given attribution as the author of +the parts of the library used. This can be in the form of a textual +message at program startup or in documentation (online or textual) +provided with the package. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. All advertising materials mentioning features or use of this +software must display the following acknowledgement:" This product +includes cryptographic software written by Eric Young +(eay@cryptsoft.com)" The word 'cryptographic' can be left out if +the rouines from the library being used are not cryptographic +related :-). + +4. If you include any Windows specific code (or a derivative thereof) +from the apps directory (application code) you must include an +acknowledgement: "This product includes software written by Tim Hudson +(tjh@cryptsoft.com)" + +THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +The licence and distribution terms for any publically available +version or derivative of this code cannot be changed. i.e. this +code cannot simply be copied and put under another distribution +licence [including the GNU Public Licence.] + + +Open Source Software Licensed under the BSD 3-Clause License: +-------------------------------------------------------------------- +1. grpc 0.14.0.dev0 +Copyright 2015, Google Inc. +All rights reserved. + +2. glog 0.3.3 +Copyright (c) 2008, Google Inc. +All rights reserved. +Copyright (c) 2003-2008, Jouni Malinen and contributors +All Rights Reserved. + +3. leveldb 1.1 +Copyright (c) 2011 The LevelDB Authors. +All rights reserved. + +4. protobuf 3.0.0-beta-1 +Copyright 2014, Google Inc. +All rights reserved. + +5. googletest 1.6.0 +Copyright 2008, Google Inc. +All rights reserved. + + +Terms of the BSD 3-Clause License: +-------------------------------------------------------------------- + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1 Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2 Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3 Neither the name of [copyright holder] nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 000000000..367d83ce4 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,204 @@ +phxpaxos-0.9.0/MANIFEST +phxpaxos-0.9.0/autoinstall.sh +phxpaxos-0.9.0/include/phxpaxos/node.h +phxpaxos-0.9.0/include/phxpaxos/def.h +phxpaxos-0.9.0/include/phxpaxos/network.h +phxpaxos-0.9.0/include/phxpaxos/options.h +phxpaxos-0.9.0/include/phxpaxos/breakpoint.h +phxpaxos-0.9.0/include/phxpaxos/sm.h +phxpaxos-0.9.0/include/phxpaxos/storage.h +phxpaxos-0.9.0/include/phxpaxos/log.h +phxpaxos-0.9.0/makefile.mk +phxpaxos-0.9.0/LICENSE +phxpaxos-0.9.0/plugin/include/phxpaxos_plugin/logger_google.h +phxpaxos-0.9.0/plugin/include/phxpaxos_plugin/monitor.h +phxpaxos-0.9.0/plugin/logger_google/logger_google.cpp +phxpaxos-0.9.0/plugin/logger_google/logger_google_impl.h +phxpaxos-0.9.0/plugin/logger_google/logger_google_impl.cpp +phxpaxos-0.9.0/plugin/monitor/monitor_bp.h +phxpaxos-0.9.0/plugin/monitor/monitor_bp.cpp +phxpaxos-0.9.0/plugin/monitor/monitor.cpp +phxpaxos-0.9.0/INSTALL +phxpaxos-0.9.0/tools/build_comm.py +phxpaxos-0.9.0/tools/create_makefile.py +phxpaxos-0.9.0/tools/build_comm.pyc +phxpaxos-0.9.0/tools/check_install.py +phxpaxos-0.9.0/sample/phxelection/election.h +phxpaxos-0.9.0/sample/phxelection/election_main.cpp +phxpaxos-0.9.0/sample/phxelection/election.cpp +phxpaxos-0.9.0/sample/phxelection/README +phxpaxos-0.9.0/sample/phxelection/run_election_sample.sh +phxpaxos-0.9.0/sample/phxecho/echo_sm.h +phxpaxos-0.9.0/sample/phxecho/echo_server.h +phxpaxos-0.9.0/sample/phxecho/run_echo.sh +phxpaxos-0.9.0/sample/phxecho/echo_sm.cpp +phxpaxos-0.9.0/sample/phxecho/echo_server.cpp +phxpaxos-0.9.0/sample/phxecho/README +phxpaxos-0.9.0/sample/phxecho/main.cpp +phxpaxos-0.9.0/sample/phxkv/client_tools_sample.sh +phxpaxos-0.9.0/sample/phxkv/kv.h +phxpaxos-0.9.0/sample/phxkv/phxkv.proto +phxpaxos-0.9.0/sample/phxkv/log.cpp +phxpaxos-0.9.0/sample/phxkv/kv_paxos.h +phxpaxos-0.9.0/sample/phxkv/def.h +phxpaxos-0.9.0/sample/phxkv/kv_grpc_client_main.cpp +phxpaxos-0.9.0/sample/phxkv/kv_grpc_server_main.cpp +phxpaxos-0.9.0/sample/phxkv/kv_paxos.cpp +phxpaxos-0.9.0/sample/phxkv/utils.cpp +phxpaxos-0.9.0/sample/phxkv/phxkv.pb.cc +phxpaxos-0.9.0/sample/phxkv/kvsm.h +phxpaxos-0.9.0/sample/phxkv/README +phxpaxos-0.9.0/sample/phxkv/phxkv.grpc.pb.cc +phxpaxos-0.9.0/sample/phxkv/kv_grpc_server.cpp +phxpaxos-0.9.0/sample/phxkv/phxkv.pb.h +phxpaxos-0.9.0/sample/phxkv/kvsm.cpp +phxpaxos-0.9.0/sample/phxkv/kv_grpc_client.h +phxpaxos-0.9.0/sample/phxkv/kv.cpp +phxpaxos-0.9.0/sample/phxkv/prepare_dir.sh +phxpaxos-0.9.0/sample/phxkv/utils.h +phxpaxos-0.9.0/sample/phxkv/kv_grpc_server.h +phxpaxos-0.9.0/sample/phxkv/log.h +phxpaxos-0.9.0/sample/phxkv/phxkv.grpc.pb.h +phxpaxos-0.9.0/sample/phxkv/kv_grpc_client.cpp +phxpaxos-0.9.0/sample/phxkv/run_server_sample.sh +phxpaxos-0.9.0/README.md +phxpaxos-0.9.0/README +phxpaxos-0.9.0/license.py +phxpaxos-0.9.0/src/logstorage/paxos_log.cpp +phxpaxos-0.9.0/src/logstorage/system_variables_store.cpp +phxpaxos-0.9.0/src/logstorage/db.cpp +phxpaxos-0.9.0/src/logstorage/log_store.h +phxpaxos-0.9.0/src/logstorage/db.h +phxpaxos-0.9.0/src/logstorage/paxos_log.h +phxpaxos-0.9.0/src/logstorage/system_variables_store.h +phxpaxos-0.9.0/src/logstorage/log_store.cpp +phxpaxos-0.9.0/src/checkpoint/replayer.h +phxpaxos-0.9.0/src/checkpoint/cleaner.cpp +phxpaxos-0.9.0/src/checkpoint/replayer.cpp +phxpaxos-0.9.0/src/checkpoint/cleaner.h +phxpaxos-0.9.0/src/checkpoint/cp_mgr.h +phxpaxos-0.9.0/src/checkpoint/cp_mgr.cpp +phxpaxos-0.9.0/src/utils/concurrent.h +phxpaxos-0.9.0/src/utils/util.h +phxpaxos-0.9.0/src/utils/bytes_buffer.h +phxpaxos-0.9.0/src/utils/crc32.cpp +phxpaxos-0.9.0/src/utils/utils_include.h +phxpaxos-0.9.0/src/utils/serial_lock.h +phxpaxos-0.9.0/src/utils/wait_lock.cpp +phxpaxos-0.9.0/src/utils/bytes_buffer.cpp +phxpaxos-0.9.0/src/utils/timer.h +phxpaxos-0.9.0/src/utils/util.cpp +phxpaxos-0.9.0/src/utils/socket.h +phxpaxos-0.9.0/src/utils/timer.cpp +phxpaxos-0.9.0/src/utils/wait_lock.h +phxpaxos-0.9.0/src/utils/socket.cpp +phxpaxos-0.9.0/src/utils/crc32.h +phxpaxos-0.9.0/src/utils/concurrent.cpp +phxpaxos-0.9.0/src/utils/serial_lock.cpp +phxpaxos-0.9.0/src/node/group.cpp +phxpaxos-0.9.0/src/node/pnode.h +phxpaxos-0.9.0/src/node/group.h +phxpaxos-0.9.0/src/node/pnode.cpp +phxpaxos-0.9.0/src/node/node.cpp +phxpaxos-0.9.0/src/algorithm/learner_sender.cpp +phxpaxos-0.9.0/src/algorithm/msg_counter.h +phxpaxos-0.9.0/src/algorithm/commitctx.cpp +phxpaxos-0.9.0/src/algorithm/learner.cpp +phxpaxos-0.9.0/src/algorithm/learner_sender.h +phxpaxos-0.9.0/src/algorithm/msg_counter.cpp +phxpaxos-0.9.0/src/algorithm/checkpoint_sender.cpp +phxpaxos-0.9.0/src/algorithm/base.h +phxpaxos-0.9.0/src/algorithm/instance.cpp +phxpaxos-0.9.0/src/algorithm/checkpoint_receiver.h +phxpaxos-0.9.0/src/algorithm/instance.h +phxpaxos-0.9.0/src/algorithm/ioloop.h +phxpaxos-0.9.0/src/algorithm/acceptor.cpp +phxpaxos-0.9.0/src/algorithm/proposer.h +phxpaxos-0.9.0/src/algorithm/committer.cpp +phxpaxos-0.9.0/src/algorithm/commitctx.h +phxpaxos-0.9.0/src/algorithm/checkpoint_sender.h +phxpaxos-0.9.0/src/algorithm/committer.h +phxpaxos-0.9.0/src/algorithm/base.cpp +phxpaxos-0.9.0/src/algorithm/learner.h +phxpaxos-0.9.0/src/algorithm/checkpoint_receiver.cpp +phxpaxos-0.9.0/src/algorithm/acceptor.h +phxpaxos-0.9.0/src/algorithm/proposer.cpp +phxpaxos-0.9.0/src/algorithm/ioloop.cpp +phxpaxos-0.9.0/src/ut/make_class.cpp +phxpaxos-0.9.0/src/ut/mock_class.h +phxpaxos-0.9.0/src/ut/make_class.h +phxpaxos-0.9.0/src/ut/db_ut.cpp +phxpaxos-0.9.0/src/ut/wait_lock_ut.cpp +phxpaxos-0.9.0/src/ut/ut_main.cpp +phxpaxos-0.9.0/src/ut/acceptor_ut.cpp +phxpaxos-0.9.0/src/ut/proposer_ut.cpp +phxpaxos-0.9.0/src/ut/timer_ut.cpp +phxpaxos-0.9.0/src/ut/nodeid_ut.cpp +phxpaxos-0.9.0/src/comm/inside_options.h +phxpaxos-0.9.0/src/comm/options.cpp +phxpaxos-0.9.0/src/comm/logger.cpp +phxpaxos-0.9.0/src/comm/comm_include.h +phxpaxos-0.9.0/src/comm/paxos_msg.pb.cc +phxpaxos-0.9.0/src/comm/breakpoint.cpp +phxpaxos-0.9.0/src/comm/commdef.h +phxpaxos-0.9.0/src/comm/paxos_msg.pb.h +phxpaxos-0.9.0/src/comm/msg_transport.h +phxpaxos-0.9.0/src/comm/paxos_msg.proto +phxpaxos-0.9.0/src/comm/logger.h +phxpaxos-0.9.0/src/comm/inside_options.cpp +phxpaxos-0.9.0/src/tools/paxos_log_tools.cpp +phxpaxos-0.9.0/src/tools/run_svm_tools.sh +phxpaxos-0.9.0/src/tools/system_variables_tools.cpp +phxpaxos-0.9.0/src/sm-base/sm_base.h +phxpaxos-0.9.0/src/sm-base/sm.cpp +phxpaxos-0.9.0/src/sm-base/sm_base.cpp +phxpaxos-0.9.0/src/master/master_variables_store.h +phxpaxos-0.9.0/src/master/master_sm.cpp +phxpaxos-0.9.0/src/master/master_sm.proto +phxpaxos-0.9.0/src/master/master_sm.pb.h +phxpaxos-0.9.0/src/master/master_sm.h +phxpaxos-0.9.0/src/master/master_variables_store.cpp +phxpaxos-0.9.0/src/master/master_damon.h +phxpaxos-0.9.0/src/master/master_damon.cpp +phxpaxos-0.9.0/src/master/master_sm.pb.cc +phxpaxos-0.9.0/src/benchmark/bench_sm.cpp +phxpaxos-0.9.0/src/benchmark/bench_server.cpp +phxpaxos-0.9.0/src/benchmark/bench_server.h +phxpaxos-0.9.0/src/benchmark/bench_sm.h +phxpaxos-0.9.0/src/benchmark/HOW_TO_BENCH +phxpaxos-0.9.0/src/benchmark/fsync_bench.cpp +phxpaxos-0.9.0/src/benchmark/bench_main.cpp +phxpaxos-0.9.0/src/config/inside_sm.h +phxpaxos-0.9.0/src/config/config.cpp +phxpaxos-0.9.0/src/config/system_v_sm.h +phxpaxos-0.9.0/src/config/system_v_sm.cpp +phxpaxos-0.9.0/src/config/config_include.h +phxpaxos-0.9.0/src/config/config.h +phxpaxos-0.9.0/src/communicate/dfnetwork.cpp +phxpaxos-0.9.0/src/communicate/network.cpp +phxpaxos-0.9.0/src/communicate/udp.cpp +phxpaxos-0.9.0/src/communicate/communicate.cpp +phxpaxos-0.9.0/src/communicate/dfnetwork.h +phxpaxos-0.9.0/src/communicate/tcp/tcp_acceptor.h +phxpaxos-0.9.0/src/communicate/tcp/tcp.cpp +phxpaxos-0.9.0/src/communicate/tcp/event_loop.h +phxpaxos-0.9.0/src/communicate/tcp/event_base.h +phxpaxos-0.9.0/src/communicate/tcp/tcp_acceptor.cpp +phxpaxos-0.9.0/src/communicate/tcp/message_event.h +phxpaxos-0.9.0/src/communicate/tcp/notify.h +phxpaxos-0.9.0/src/communicate/tcp/event_loop.cpp +phxpaxos-0.9.0/src/communicate/tcp/event_base.cpp +phxpaxos-0.9.0/src/communicate/tcp/tcp_client.h +phxpaxos-0.9.0/src/communicate/tcp/tcp_client.cpp +phxpaxos-0.9.0/src/communicate/tcp/tcp.h +phxpaxos-0.9.0/src/communicate/tcp/message_event.cpp +phxpaxos-0.9.0/src/communicate/tcp/notify.cpp +phxpaxos-0.9.0/src/communicate/communicate.h +phxpaxos-0.9.0/src/communicate/udp.h +phxpaxos-0.9.0/src/test/test_sm.h +phxpaxos-0.9.0/src/test/test_server.h +phxpaxos-0.9.0/src/test/test_server.cpp +phxpaxos-0.9.0/src/test/test_main.cpp +phxpaxos-0.9.0/src/test/test_sm.cpp +phxpaxos-0.9.0/src_list +phxpaxos-0.9.0/AUTHORS diff --git a/Makefile.define b/Makefile.define new file mode 100644 index 000000000..433a9b007 --- /dev/null +++ b/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=elibphxpaxos.a + +PHXPAXOS_OBJ= + +PHXPAXOS_LIB=src/node:node include:include + +PHXPAXOS_SYS_LIB= + +PHXPAXOS_INCS=$(SRC_BASE_PATH)/ + +PHXPAXOS_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/README b/README new file mode 100644 index 000000000..72f3787ab --- /dev/null +++ b/README @@ -0,0 +1,4 @@ +This repository contains a C++ implementation of the Phxpaxos module. + +See INSTALL for (generic) installation instructions for C++: basically + sh autoinstall.sh && make && make install diff --git a/autoinstall.sh b/autoinstall.sh new file mode 100755 index 000000000..d3bbade33 --- /dev/null +++ b/autoinstall.sh @@ -0,0 +1,97 @@ +#!/bin/bash + +base_dir=`pwd` +make_file_tools=$base_dir/tools/create_makefile.py +check_env_tools=$base_dir/tools/check_install.py +src_dir=$base_dir/src_list + +function check_env(){ + python $check_env_tools $base_dir + if [ $? -gt 0 ]; + then + exit 1 + fi +} + +function create_makefile(){ + python $make_file_tools $base_dir $1 +} + +function scandir(){ + if [ $1 ];then + echo "[creating makefile] $1" + create_makefile $1 + for file in `ls $1` + do + if ([ -d $1"/"$file ] && [ "$file" != "glog" ]) + then + scandir $1"/"$file + fi + done + fi +} + +function process(){ + create_makefile $base_dir + res=`cat $src_dir` + echo $res + for file in $res + do + if ([ -d $base_dir"/"$file ] && [ "$file" != "glog" ]) + then + scandir $base_dir"/"$file + fi + done +} + +function check(){ + make verify-install --file=makefile.mk + if [ $? -eq 0 ]; then + return 0 + else + echo "install fail" + return 1 + fi +} + +function showusage(){ + echo "Configuration:" + echo " -h, --help display this help and exit" + echo "Installation directories:" + echo " --prefix=PREFIX install architecture-independent files in PREFIX" + echo " [.]" + exit +} + +prefix= + +ARGS=`getopt -o h -l prefix:,help -- "$@"` +eval set -- "${ARGS}" + +while true +do + case "$1" in + --prefix) + if [ $2 ]; then + sed -i -r "s#PREFIX=.*#PREFIX=$2#" makefile.mk + fi + shift + ;; + -h|--help) + showusage + break + ;; + --) + shift + break + ;; + esac +shift +done + +check_env +echo "check evn done" +#check +if [ $? -eq 0 ]; then +process +fi diff --git a/include/Makefile.define b/include/Makefile.define new file mode 100644 index 000000000..c0e86feb2 --- /dev/null +++ b/include/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libinclude.a + +INCLUDE_OBJ= + +INCLUDE_LIB= + +INCLUDE_SYS_LIB= + +INCLUDE_INCS=$(SRC_BASE_PATH)/include + +INCLUDE_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/include/phxpaxos/breakpoint.h b/include/phxpaxos/breakpoint.h new file mode 100644 index 000000000..fe0df61b4 --- /dev/null +++ b/include/phxpaxos/breakpoint.h @@ -0,0 +1,246 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include + +namespace phxpaxos +{ + +class ProposerBP +{ +public: + virtual ~ProposerBP() { } + virtual void NewProposal(const std::string & sValue) { } + virtual void NewProposalSkipPrepare() { } + virtual void Prepare() { } + virtual void OnPrepareReply() { } + virtual void OnPrepareReplyButNotPreparing() { } + virtual void OnPrepareReplyNotSameProposalIDMsg() { } + virtual void PreparePass(const int iUseTimeMs) { } + virtual void PrepareNotPass() { } + virtual void Accept() { } + virtual void OnAcceptReply() { } + virtual void OnAcceptReplyButNotAccepting() { } + virtual void OnAcceptReplyNotSameProposalIDMsg() { } + virtual void AcceptPass(const int iUseTimeMs) { } + virtual void AcceptNotPass() { } + virtual void PrepareTimeout() { } + virtual void AcceptTimeout() { } +}; + +class AcceptorBP +{ +public: + virtual ~AcceptorBP() { } + virtual void OnPrepare() { } + virtual void OnPreparePass() { } + virtual void OnPreparePersistFail() { } + virtual void OnPrepareReject() { } + virtual void OnAccept() { } + virtual void OnAcceptPass() { } + virtual void OnAcceptPersistFail() { } + virtual void OnAcceptReject() { } +}; + +class LearnerBP +{ +public: + virtual ~LearnerBP() { } + virtual void AskforLearn() { } + virtual void OnAskforLearn() { } + virtual void OnAskforLearnGetLockFail() { } + virtual void SendNowInstanceID() { } + virtual void OnSendNowInstanceID() { } + virtual void ComfirmAskForLearn() { } + virtual void OnComfirmAskForLearn() { } + virtual void OnComfirmAskForLearnGetLockFail() { } + virtual void SendLearnValue() { } + virtual void OnSendLearnValue() { } + virtual void SendLearnValue_Ack() { } + virtual void OnSendLearnValue_Ack() { } + virtual void ProposerSendSuccess() { } + virtual void OnProposerSendSuccess() { } + virtual void OnProposerSendSuccessNotAcceptYet() { } + virtual void OnProposerSendSuccessBallotNotSame() { } + virtual void OnProposerSendSuccessSuccessLearn() { } + virtual void SenderAckTimeout() { } + virtual void SenderAckDelay() { } + virtual void SenderSendOnePaxosLog() { } +}; + +class InstanceBP +{ +public: + virtual ~InstanceBP() { } + virtual void NewInstance() { } + virtual void SendMessage() { } + virtual void BroadcastMessage() { } + virtual void OnNewValueCommitTimeout() { } + virtual void OnReceive() { } + virtual void OnReceiveParseError() { } + virtual void OnReceivePaxosMsg() { } + virtual void OnReceivePaxosMsgNodeIDNotValid() { } + virtual void OnReceivePaxosMsgTypeNotValid() { } + virtual void OnReceivePaxosProposerMsgInotsame() { } + virtual void OnReceivePaxosAcceptorMsgInotsame() { } + virtual void OnReceivePaxosAcceptorMsgAddRetry() { } + virtual void OnInstanceLearned() { } + virtual void OnInstanceLearnedNotMyCommit() { } + virtual void OnInstanceLearnedIsMyCommit(const int iUseTimeMs) { } + virtual void OnInstanceLearnedSMExecuteFail() { } + virtual void ChecksumLogicFail() { } +}; + +class CommiterBP +{ +public: + virtual ~CommiterBP() { } + virtual void NewValue() { } + virtual void NewValueConflict() { } + virtual void NewValueGetLockTimeout() { } + virtual void NewValueGetLockOK(const int iUseTimeMs) { } + virtual void NewValueCommitOK(const int iUseTimeMs) { } + virtual void NewValueCommitFail() { } +}; + +class IOLoopBP +{ +public: + virtual ~IOLoopBP() { } + virtual void OneLoop() { } + virtual void EnqueueMsg() { } + virtual void EnqueueMsgRejectByFullQueue() { } + virtual void EnqueueRetryMsg() { } + virtual void EnqueueRetryMsgRejectByFullQueue() { } + virtual void OutQueueMsg() { } + virtual void DealWithRetryMsg() { } +}; + +class NetworkBP +{ +public: + virtual ~NetworkBP() { } + virtual void TcpEpollLoop() { } + virtual void TcpOnError() { } + virtual void TcpAcceptFd() { } + virtual void TcpQueueFull() { } + virtual void TcpReadOneMessageOk(const int iLen) { } + virtual void TcpOnReadMessageLenError() { } + virtual void TcpReconnect() { } + virtual void SendRejectByTooLargeSize() { } + virtual void Send(const std::string & sMessage) { } + virtual void SendTcp(const std::string & sMessage) { } + virtual void SendUdp(const std::string & sMessage) { } + virtual void SendMessageNodeIDNotFound() { } + virtual void UDPReceive(const int iRecvLen) { } + virtual void UDPRealSend(const std::string & sMessage) { } + virtual void UDPQueueFull() { } +}; + +class LogStorageBP +{ +public: + virtual ~LogStorageBP() { } + virtual void LevelDBGetNotExist() { } + virtual void LevelDBGetFail() { } + virtual void FileIDToValueFail() { } + virtual void ValueToFileIDFail() { } + virtual void LevelDBPutFail() { } + virtual void LevelDBPutOK(const int iUseTimeMs) { } + virtual void AppendDataFail() { } + virtual void AppendDataOK(const int iWriteLen, const int iUseTimeMs) { } + virtual void GetFileChecksumNotEquel() { } +}; + +class AlgorithmBaseBP +{ +public: + virtual ~AlgorithmBaseBP() { } + virtual void UnPackHeaderLenTooLong() { } + virtual void UnPackChecksumNotSame() { } + virtual void HeaderGidNotSame() { } +}; + +class CheckpointBP +{ +public: + virtual ~CheckpointBP() { } + virtual void NeedAskforCheckpoint() { } + virtual void SendCheckpointOneBlock() { } + virtual void OnSendCheckpointOneBlock() { } + virtual void SendCheckpointBegin() { } + virtual void SendCheckpointEnd() { } + virtual void ReceiveCheckpointDone() { } + virtual void ReceiveCheckpointAndLoadFail() { } + virtual void ReceiveCheckpointAndLoadSucc() { } +}; + +#define BP (Breakpoint::Instance()) + +class Breakpoint +{ +public: + Breakpoint(); + + virtual ~Breakpoint() { } + + void SetInstance(Breakpoint * poBreakpoint); + + static Breakpoint * Instance(); + + virtual ProposerBP * GetProposerBP(); + + virtual AcceptorBP * GetAcceptorBP(); + + virtual LearnerBP * GetLearnerBP(); + + virtual InstanceBP * GetInstanceBP(); + + virtual CommiterBP * GetCommiterBP(); + + virtual IOLoopBP * GetIOLoopBP(); + + virtual NetworkBP * GetNetworkBP(); + + virtual LogStorageBP * GetLogStorageBP(); + + virtual AlgorithmBaseBP * GetAlgorithmBaseBP(); + + virtual CheckpointBP * GetCheckpointBP(); + +public: + ProposerBP m_oProposerBP; + AcceptorBP m_oAcceptorBP; + LearnerBP m_oLearnerBP; + InstanceBP m_oInstanceBP; + CommiterBP m_oCommiterBP; + IOLoopBP m_oIOLoopBP; + NetworkBP m_oNetworkBP; + LogStorageBP m_oLogStorageBP; + AlgorithmBaseBP m_oAlgorithmBaseBP; + CheckpointBP m_oCheckpointBP; + + static Breakpoint * m_poBreakpoint; +}; + +} diff --git a/include/phxpaxos/def.h b/include/phxpaxos/def.h new file mode 100644 index 000000000..c59941563 --- /dev/null +++ b/include/phxpaxos/def.h @@ -0,0 +1,55 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +namespace phxpaxos +{ + +#define SYSTEM_V_SMID 100000000 +#define MASTER_V_SMID 100000001 + +enum PaxosTryCommitRet +{ + PaxosTryCommitRet_OK = 0, + PaxosTryCommitRet_Reject = -2, + PaxosTryCommitRet_Conflict = 14, + PaxosTryCommitRet_ExecuteFail = 15, + PaxosTryCommitRet_Follower_Cannot_Commit = 16, + PaxosTryCommitRet_Im_Not_In_Membership = 17, + PaxosTryCommitRet_Value_Size_TooLarge = 18, + PaxosTryCommitRet_Timeout = 404, +}; + +enum PaxosNodeFunctionRet +{ + Paxos_SystemError = -1, + Paxos_GroupIdxWrong = -5, + Paxos_MembershipOp_GidNotSame = -501, + Paxos_MembershipOp_VersionConflit = -502, + Paxos_MembershipOp_NoGid = 1001, + Paxos_MembershipOp_Add_NodeExist = 1002, + Paxos_MembershipOp_Remove_NodeNotExist = 1003, + Paxos_MembershipOp_Change_NoChange = 1004, +}; + +} + diff --git a/include/phxpaxos/log.h b/include/phxpaxos/log.h new file mode 100644 index 000000000..2684a4611 --- /dev/null +++ b/include/phxpaxos/log.h @@ -0,0 +1,40 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include + +namespace phxpaxos +{ + +enum class LogLevel +{ + LogLevel_None = 0, + LogLevel_Error = 1, + LogLevel_Warning = 2, + LogLevel_Info = 3, + LogLevel_Verbose = 4, +}; + +typedef void (*LogFunc)(const int iLogLevel, const char * pcFormat, va_list args); + +} diff --git a/include/phxpaxos/network.h b/include/phxpaxos/network.h new file mode 100644 index 000000000..58bd2d6d5 --- /dev/null +++ b/include/phxpaxos/network.h @@ -0,0 +1,60 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include + +namespace phxpaxos +{ + +//You can use your own network to make paxos communicate. :) + +class Node; + +class NetWork +{ +public: + NetWork(); + virtual ~NetWork() {} + + //Network must not send/recieve any message before paxoslib called this funtion. + virtual void RunNetWork() = 0; + + //If paxoslib call this function, network need to stop receive any message. + virtual void StopNetWork() = 0; + + virtual int SendMessageTCP(const std::string & sIp, const int iPort, const std::string & sMessage) = 0; + + virtual int SendMessageUDP(const std::string & sIp, const int iPort, const std::string & sMessage) = 0; + + //When receive a message, call this funtion. + //This funtion is async, just enqueue an return. + int OnReceiveMessage(const char * pcMessage, const int iMessageLen); + +private: + friend class Node; + Node * m_poNode; +}; + +} diff --git a/include/phxpaxos/node.h b/include/phxpaxos/node.h new file mode 100644 index 000000000..d40f7336e --- /dev/null +++ b/include/phxpaxos/node.h @@ -0,0 +1,108 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/sm.h" +#include "phxpaxos/options.h" +#include +#include + +namespace phxpaxos +{ + +class NetWork; + +//All the funciton in class Node is thread safe! + +class Node +{ +public: + Node() { } + virtual ~Node() { } + + //If you want to end paxos, just delete poNode. + //But if you use your own network, poNode can be deleted after your own network stop recieving messages. + static int RunNode(const Options & oOptions, Node *& poNode); + + //Base function. + virtual int Propose(const int iGroupIdx, const std::string & sValue, uint64_t & llInstanceID) = 0; + + virtual int Propose(const int iGroupIdx, const std::string & sValue, uint64_t & llInstanceID, SMCtx * poSMCtx) = 0; + + virtual const uint64_t GetNowInstanceID(const int iGroupIdx) = 0; + + virtual const nodeid_t GetMyNodeID() const = 0; + + //State machine. + + //This function will add state machine to all group. + virtual void AddStateMachine(StateMachine * poSM) = 0; + + virtual void AddStateMachine(const int iGroupIdx, StateMachine * poSM) = 0; + + //Timeout control. + virtual void SetTimeoutMs(const int iTimeoutMs) = 0; + + //Checkpoint + + //Set the number you want to keep paxoslog's count. + //We will only delete paxoslog before checkpoint instanceid. + virtual void SetHoldPaxosLogCount(const uint64_t llHoldCount) = 0; + + //Replayer is to help sm make checkpoint. + //Checkpoint replayer default is paused, if you not use this, ignord this function. + //If sm use ExecuteForCheckpoint to make checkpoint, you need to run replayer(you can run in any time). + + //Pause checkpoint replayer. + virtual void PauseCheckpointReplayer() = 0; + + //Continue to run replayer + virtual void ContinueCheckpointReplayer() = 0; + + //Paxos log cleaner working for deleting paxoslog before checkpoint instanceid. + //Paxos log cleaner default is running. + + //pause paxos log cleaner. + virtual void PausePaxosLogCleaner() = 0; + + //Continue to run paxos log cleaner. + virtual void ContinuePaxosLogCleaner() = 0; + + //Master + + //Check who is master. + virtual const NodeInfo GetMaster(const int iGroupIdx) = 0; + + //Check is i'm master. + virtual const bool IsIMMaster(const int iGroupIdx) = 0; + + virtual int SetMasterLease(const int iGroupIdx, const int iLeaseTimeMs) = 0; + + virtual int DropMaster(const int iGroupIdx) = 0; + +protected: + friend class NetWork; + + virtual int OnReceiveMessage(const char * pcMessage, const int iMessageLen) = 0; +}; + +} diff --git a/include/phxpaxos/options.h b/include/phxpaxos/options.h new file mode 100644 index 000000000..3634b2ebc --- /dev/null +++ b/include/phxpaxos/options.h @@ -0,0 +1,187 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/def.h" +#include "phxpaxos/sm.h" +#include "phxpaxos/network.h" +#include "phxpaxos/storage.h" +#include "phxpaxos/log.h" +#include +#include +#include +#include "breakpoint.h" + +namespace phxpaxos +{ + +class LogStorage; +class NetWork; +class StateMachine; + +typedef uint64_t nodeid_t; +static const nodeid_t nullnode = 0; + +/////////////////////////////////////////////// + +class NodeInfo +{ +public: + NodeInfo(); + NodeInfo(const nodeid_t iNodeID); + NodeInfo(const std::string & sIP, const int iPort); + virtual ~NodeInfo() { } + + const nodeid_t GetNodeID() const; + const std::string & GetIP() const; + const int GetPort() const; + + void SetIPPort(const std::string & sIP, const int iPort); + void SetNodeID(const nodeid_t iNodeID); + +private: + void MakeNodeID(); + void ParseNodeID(); + + nodeid_t m_iNodeID; + std::string m_sIP; + int m_iPort; +}; + +class FollowerNodeInfo +{ +public: + NodeInfo oMyNode; + NodeInfo oFollowNode; +}; + +typedef std::vector NodeInfoList; +typedef std::vector FollowerNodeInfoList; + +///////////////////////////////////////////////// + +class GroupSMInfo +{ +public: + GroupSMInfo(); + + //required + //GroupIdx interval is [0, iGroupCount) + int iGroupIdx; + + //optional + //One paxos group can mounting multi state machines. + std::vector vecSMList; + + //optional + //Master election is a internal state machine. + //Set bIsUseMaster as true to open master election feature. + //Default is false. + bool bIsUseMaster; + +}; + +typedef std::vector GroupSMInfoList; + +///////////////////////////////////////////////// + +typedef void (*MembershipChangeCallback)(const int iGroupIdx, NodeInfoList & vecNodeInfoList); + +///////////////////////////////////////////////// + +class Options +{ +public: + Options(); + + //optional + //User-specified paxoslog storage. + //Default is nullptr. + LogStorage * poLogStorage; + + //optional + //If poLogStorage == nullptr, sLogStoragePath is required. + std::string sLogStoragePath; + + //optional + //User-specified network. + NetWork * poNetWork; + + //optional + //Our default network use udp and tcp combination, a message we use udp or tcp to send decide by a threshold. + //Message size under iUDPMaxSize we use udp to send. + //Default is 2048. + size_t iUDPMaxSize; + + //optional + //We support to run multi phxpaxos on one process. + //One paxos group here means one independent phxpaxos. Any two phxpaxos(paxos group) only share network, no other. + //There is no communication between any two paxos group. + //Default is 1. + int iGroupCount; + + //required + //Self node's ip/port. + NodeInfo oMyNode; + + //required + //All nodes's ip/port with a paxos set(usually three or five nodes). + NodeInfoList vecNodeInfoList; + + //optional + //One phxpaxos can mounting multi state machines. + //This vector include different phxpaxos's state machines list. + GroupSMInfoList vecGroupSMInfoList; + + //optional + Breakpoint * poBreakpoint; + + //optional + //If use this mode, that means you propose large value(maybe large than 5M means large) much more. + //Large value means long latency, long timeout, this mode will fit it. + //Default is false + bool bIsLargeValueMode; + + //optional + //All followers's ip/port, and follow to node's ip/port. + //Follower only learn but not participation paxos algorithmic process. + //Default is empty. + FollowerNodeInfoList vecFollowerNodeInfoList; + + //optional + //Notice, this function must be thread safe! + //if pLogFunc == nullptr, we will print log to standard ouput. + LogFunc pLogFunc; + + //optional + //If you use your own log function, then you control loglevel yourself, ignore this. + //Check log.h to find 5 level. + //Default is LogLevel::LogLevel_None, that means print no log. + LogLevel eLogLevel; + + //optional + //If you use checkpoint replayer feature, set as true. + //Default is false; + bool bUseCheckpointReplayer; +}; + +} diff --git a/include/phxpaxos/sm.h b/include/phxpaxos/sm.h new file mode 100644 index 000000000..22de43da9 --- /dev/null +++ b/include/phxpaxos/sm.h @@ -0,0 +1,103 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include +#include +#include + +namespace phxpaxos +{ + +class SMCtx +{ +public: + SMCtx(); + SMCtx(const int iSMID, void * pCtx); + + int m_iSMID; + void * m_pCtx; +}; + +////////////////////////////////////////////// + +class CheckpointFileInfo +{ +public: + std::string m_sFilePath; + size_t m_llFileSize; +}; + +typedef std::vector CheckpointFileInfoList; + +///////////////////////////////////////////// + +const uint64_t NoCheckpoint = (uint64_t)-1; + +class StateMachine +{ +public: + virtual ~StateMachine() {} + + //Return true means execute success. + //This 'success' means this execute don't need to retry. + //Sometimes you will have some logical failure in your execute logic, + //and this failure will definite occur on all node, that means this failure is acceptable, + //for this case, return true is the best choice. + //Some system failure will let different node's execute result inconsistent, + //for this case, you must return false to retry this execute to avoid this system failure. + virtual bool Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, SMCtx * poSMCtx) = 0; + + //Different state machine return different SMID(). + virtual const int SMID() const = 0; + + virtual bool ExecuteForCheckpoint(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue); + + //Only need to implement this function while you have checkpoint. + //Return your checkpoint's max executed instanceid. + //Notice PhxPaxos will call this function very frequently. + virtual const uint64_t GetCheckpointInstanceID(const int iGroupIdx) const; + + //After called this function, the vecFileList that GetCheckpointState return's, can't be delelted, moved and modifyed. + virtual int LockCheckpointState(); + + //sDirpath is checkpoint data root dir path. + //vecFileList is the relative path of the sDirPath. + virtual int GetCheckpointState(const int iGroupIdx, std::string & sDirPath, + std::vector & vecFileList); + + virtual void UnLockCheckpointState(); + + //Checkpoint file was on dir(sCheckpointTmpFileDirPath). + //vecFileList is all the file in dir(sCheckpointTmpFileDirPath). + //vecFileList filepath is absolute path. + //After called this fuction, paxoslib will kill the processor. + //State machine need to understand this when restart. + virtual int LoadCheckpointState(const int iGroupIdx, const std::string & sCheckpointTmpFileDirPath, + const std::vector & vecFileList, const uint64_t llCheckpointInstanceID); +}; + +} diff --git a/include/phxpaxos/storage.h b/include/phxpaxos/storage.h new file mode 100644 index 000000000..5f0bf58d0 --- /dev/null +++ b/include/phxpaxos/storage.h @@ -0,0 +1,71 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include + +namespace phxpaxos +{ + +//Paxoslib need to storage many datas, if you want to storage datas yourself, +//you must implememt all function in class LogStorage, and make sure that observe the writeoptions. + +class WriteOptions +{ +public: + WriteOptions() : bSync(true) { } + bool bSync; +}; + +class LogStorage +{ +public: + virtual ~LogStorage() {} + + virtual const std::string GetLogStorageDirPath(const int iGroupIdx) = 0; + + virtual int Get(const int iGroupIdx, const uint64_t llInstanceID, std::string & sValue) = 0; + + virtual int Put(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID, const std::string & sValue) = 0; + + virtual int Del(const WriteOptions & oWriteOptions, int iGroupIdx, const uint64_t llInstanceID) = 0; + + virtual int GetMaxInstanceID(const int iGroupIdx, uint64_t & llInstanceID) = 0; + + virtual int SetMinChosenInstanceID(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llMinInstanceID) = 0; + + virtual int GetMinChosenInstanceID(const int iGroupIdx, uint64_t & llMinInstanceID) = 0; + + virtual int ClearAllLog(const int iGroupIdx) = 0; + + virtual int SetSystemVariables(const WriteOptions & oWriteOptions, const int iGroupIdx, const std::string & sBuffer) = 0; + + virtual int GetSystemVariables(const int iGroupIdx, std::string & sBuffer) = 0; + + virtual int SetMasterVariables(const WriteOptions & oWriteOptions, const int iGroupIdx, const std::string & sBuffer) = 0; + + virtual int GetMasterVariables(const int iGroupIdx, std::string & sBuffer) = 0; +}; + +} diff --git a/license.py b/license.py new file mode 100644 index 000000000..f577b32ce --- /dev/null +++ b/license.py @@ -0,0 +1,41 @@ +def AddLicense(file_path, license_file_path, file_type="code"): + + license_file=open(license_file_path,"r") + licenses = license_file.readlines() + license_file.close() + + add_file = open(file_path) + lines = add_file.readlines() + add_file.close() + + new_lines = [] + begin = False + for line in lines: + read_line = line.strip() + + if( file_type =="code" ): + if( len( read_line ) > 0 and read_line[0] == '#' ): + begin = True + else: + if( len( read_line ) > 0 and read_line[0] != '#' ): + begin = True + + if( begin == False ): + continue + new_lines.append( line ) + + add_file = open(file_path,'w') + + if( file_type == "Makefile" ): + for license in licenses: + add_file.write("# "+license) + else: + add_file.write("/*\n") + for license in licenses: + add_file.write("\t"+license) + add_file.write("*/\n") + add_file.write("\n") + + add_file.writelines(new_lines) + add_file.close() + diff --git a/makefile.mk b/makefile.mk new file mode 100644 index 000000000..c7679cf1c --- /dev/null +++ b/makefile.mk @@ -0,0 +1,127 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +SRC_BASE_PATH ?= . +PREFIX?=$(SRC_BASE_PATH) +PHX_LIB_PATH = $(SRC_BASE_PATH)/.lib +PHX_SBIN_PATH = $(SRC_BASE_PATH)/.sbin +PHX_EXTLIB_PATH = $(PHX_LIB_PATH)/extlib + +NANOPBPATH=$(SRC_BASE_PATH)/third_party/nanopb/ + +PROTOBUF_INCLUDE_PATH=$(SRC_BASE_PATH)/third_party/protobuf/include/ +GRPC_INCLUDE_PATH=$(SRC_BASE_PATH)/third_party/grpc/include +LEVELDB_INCLUDE_PATH=$(SRC_BASE_PATH)/third_party/leveldb/include/ +GLOG_INCLUDE_PATH=$(SRC_BASE_PATH)/third_party/glog/src/ +PHXPAXOS_INCLUDE_PATH=$(SRC_BASE_PATH)/include +PHXPAXOS_PLUGIN_PATH=$(SRC_BASE_PATH)/plugin/include + +PROTOBUF_LIB_PATH=$(SRC_BASE_PATH)/third_party/protobuf/lib +LEVELDB_LIB_PATH=$(SRC_BASE_PATH)/third_party/leveldb/lib/ +GLOG_LIB_PATH=$(SRC_BASE_PATH)/third_party/glog/lib +GRPC_LIBE_PATH=$(SRC_BASE_PATH)/third_party/grpc/lib +OPEN_SSL_LIB_PATH=$(SRC_BASE_PATH)/third_party/openssl/lib +PHXPAXOS_LIB_PATH=$(SRC_BASE_PATH)/lib + + +CXX=g++ +CXXFLAGS+=-std=c++11 +CPPFLAGS+=-I$(SRC_BASE_PATH) -I$(PROTOBUF_INCLUDE_PATH) -I$(LEVELDB_INCLUDE_PATH) +CPPFLAGS+=-I$(GLOG_INCLUDE_PATH) +CPPFLAGS+=-Wall -g -fPIC -m64 -Wno-unused-local-typedefs + +#LDFLAGS+=-shared +#LDFLAGS+=-static +LDFLAGS+=-L$(PHX_LIB_PATH) -L$(PROTOBUF_LIB_PATH) -L$(LEVELDB_LIB_PATH) +LDFLAGS+=-L$(GLOG_LIB_PATH) -L$(GRPC_LIBE_PATH) -L$(OPEN_SSL_LIB_PATH) -g + + +#===================================================================================================== + +PROTOC = $(SRC_BASE_PATH)/third_party/protobuf/bin/protoc +PROTOS_PATH = . +GRPC_CPP_PLUGIN = grpc_cpp_plugin +GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` +NANOPB_PLUGIN_PATH=$(NANOPBPATH)/generator/protoc-gen-nanopb + +vpath %.proto $(PROTOS_PATH) + +.PRECIOUS: %.grpc.pb.cc +%.grpc.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $< + +.PRECIOUS: %.nano.pb.cc +%.nano.pb.cc: %.proto + $(PROTOC) --plugin=protoc-gen-nanopb=$(NANOPB_PLUGIN_PATH) --nanopb_out=nanoproto/ $< + + +.PRECIOUS: %.pb.cc +%.pb.cc: %.proto + $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $< + + +PROTOC_CHECK_VERSION_CMD = $(PROTOC) --version | grep -q libprotoc.3 +HAS_VALID_PROTOC ?= $(shell $(PROTOC_CHECK_VERSION_CMD) 2> /dev/null && echo true || echo false) + +LEVELDB_CHECK_CMD = ls $(LEVELDB_INCLUDE_PATH) > /dev/null +HAS_LEVEL_DB_CMD ?= $(shell $(LEVELDB_CHECK_CMD) 2> /dev/null && echo true || echo false) + +.PHONY:verify-install +verify-install: +ifeq ($(HAS_VALID_PROTOC),true) + @echo "protobuf check [done]" +else + @echo "The library requires protobuf-compiler 3.0.0+" + @echo "But the third party directory doesn't have it" + @echo "Please check it and make sure the protobuf " + @echo "has been placed or linked in the third party directory" +endif + +ifeq ($(HAS_LEVEL_DB_CMD),true) + @echo "level check [done]" +else + @echo "The library requires the leveldb library" + @echo "But the third party directory doesn't have it" + @echo "Please check it and make sure the leveldb" + @echo "has been placed or linked in the third party directory" +endif + +.PHONY:install +install: + prefix_dir=`readlink $(PREFIX) -m`;\ + src_dir=`readlink $(SRC_BASE_PATH) -m`;\ + if ([ "$$prefix_dir" != "$$src_dir" ]); then \ + echo cp $(PHX_LIB_PATH) $(PREFIX)/include -rf;\ + cp $(PHXPAXOS_INCLUDE_PATH) $(PREFIX)/include -rf;\ + fi + echo INSTALL to $(PREFIX)/lib; + mkdir $(PREFIX)/lib -p;\ + rm $(PREFIX)/lib/* -rf;\ + cp $(PHX_EXTLIB_PATH)/* $(PREFIX)/lib/ -rf; + +version = 0.9.0 + +dist: clean phxpaxos-$(version).src.tar.gz +phxpaxos-$(version).src.tar.gz: + @rm -rf phxpaxos-$(version).src.tar.gz + @find . -type f | grep -v CVS | grep -v Makefile | grep -v "lib.*.a" | grep -v .svn | grep -v .git | sed s:^./:phxpaxos-$(version)/: > MANIFEST + @(cd ..; ln -s phxpaxos phxpaxos-$(version)) + (cd ..; tar cvf - `cat phxpaxos/MANIFEST` | gzip > phxpaxos/phxpaxos-$(version).src.tar.gz) + @(cd ..; rm phxpaxos-$(version)) + diff --git a/plugin/Makefile.define b/plugin/Makefile.define new file mode 100644 index 000000000..0ef947be5 --- /dev/null +++ b/plugin/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=elibphxpaxos_plugin.a + +PHXPAXOS_PLUGIN_OBJ= + +PHXPAXOS_PLUGIN_LIB=plugin/logger_google:logger_google plugin/monitor:monitor + +PHXPAXOS_PLUGIN_SYS_LIB= + +PHXPAXOS_PLUGIN_INCS=$(SRC_BASE_PATH)/plugin + +PHXPAXOS_PLUGIN_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/plugin/include/Makefile.define b/plugin/include/Makefile.define new file mode 100644 index 000000000..4dff7dc6e --- /dev/null +++ b/plugin/include/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libinclude.a + +INCLUDE_OBJ= + +INCLUDE_LIB= + +INCLUDE_SYS_LIB= + +INCLUDE_INCS=$(SRC_BASE_PATH)/plugin/include + +INCLUDE_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/plugin/include/phxpaxos_plugin/logger_google.h b/plugin/include/phxpaxos_plugin/logger_google.h new file mode 100644 index 000000000..9cb79f681 --- /dev/null +++ b/plugin/include/phxpaxos_plugin/logger_google.h @@ -0,0 +1,52 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include "phxpaxos/log.h" + +namespace phxpaxos +{ + +class LoggerGoogle +{ +public: + //LogLevel_None = 0, + //LogLevel_Error = 1, + //LogLevel_Warning = 2, + //LogLevel_Info = 3, + //LogLevel_Verbose = 4, + static int GetLogger(const std::string & sModuleName, const std::string & sLogPath, const int iLogLevel, LogFunc & pLogFunc); + + static void Log(const int iLogLevel, const char * pcFormat, va_list args); + + static void LogError(const char * pcFormat, ...); + + static void LogWarning(const char * pcFormat, ...); + + static void LogInfo(const char * pcFormat, ...); + + static void LogVerbose(const char * pcFormat, ...); +}; + +} diff --git a/plugin/include/phxpaxos_plugin/monitor.h b/plugin/include/phxpaxos_plugin/monitor.h new file mode 100644 index 000000000..f726bdca8 --- /dev/null +++ b/plugin/include/phxpaxos_plugin/monitor.h @@ -0,0 +1,46 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/breakpoint.h" + +namespace phxpaxos +{ + +class MonitorConfig +{ +public: + MonitorConfig(); + + int iOssAttrID; + int iUseTimeOssAttrID; +}; + +typedef void (*IDKeyOssFunc)(const uint32_t iOssAttrID, const uint32_t iKey, const uint32_t iVal); + +class Monitor +{ +public: + static Breakpoint * GetBreakpoint(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc); +}; + +} diff --git a/plugin/logger_google/Makefile.define b/plugin/logger_google/Makefile.define new file mode 100644 index 000000000..5a0ead747 --- /dev/null +++ b/plugin/logger_google/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=liblogger_google.a + +LOGGER_GOOGLE_OBJ=logger_google.o + +LOGGER_GOOGLE_LIB=logger_google plugin/include:include + +LOGGER_GOOGLE_SYS_LIB=$(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread $(GLOG_LIB_PATH)/libglog.a -lpthread + +LOGGER_GOOGLE_INCS=$(SRC_BASE_PATH)/plugin/logger_google $(PHXPAXOS_INCLUDE_PATH) $(LEVELDB_INCLUDE_PATH) $(PROTOBUF_INCLUDE_PATH) + +LOGGER_GOOGLE_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/plugin/logger_google/logger_google.cpp b/plugin/logger_google/logger_google.cpp new file mode 100644 index 000000000..e0d584dac --- /dev/null +++ b/plugin/logger_google/logger_google.cpp @@ -0,0 +1,116 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "phxpaxos_plugin/logger_google.h" +#include +#include + +#include +#include +#include + +using namespace std; + +namespace phxpaxos +{ + +int LoggerGoogle :: GetLogger(const std::string & sModuleName, const std::string & sLogPath, const int iLogLevel, LogFunc & pLogFunc) +{ + google::InitGoogleLogging(sModuleName.c_str()); + FLAGS_log_dir = sLogPath; + FLAGS_stderrthreshold = google :: FATAL; + switch( iLogLevel ) + { + case 1: + FLAGS_minloglevel = google::ERROR; + break; + case 2: + FLAGS_minloglevel = google::WARNING; + break; + case 3: + FLAGS_minloglevel = google::INFO; + break; + } + + LogError("%s", "init_glog_warning_file"); + + pLogFunc = LoggerGoogle::Log; + + return 0; +} + +void LoggerGoogle :: LogError(const char * pcFormat, ...) +{ + va_list args; + va_start(args, pcFormat); + Log(static_cast(LogLevel::LogLevel_Error), pcFormat, args); + va_end(args); +} + +void LoggerGoogle :: LogWarning(const char * pcFormat, ...) +{ + va_list args; + va_start(args, pcFormat); + Log(static_cast(LogLevel::LogLevel_Warning), pcFormat, args); + va_end(args); +} + +void LoggerGoogle :: LogInfo(const char * pcFormat, ...) +{ + va_list args; + va_start(args, pcFormat); + Log(static_cast(LogLevel::LogLevel_Info), pcFormat, args); + va_end(args); +} + +void LoggerGoogle :: LogVerbose(const char * pcFormat, ...) +{ + va_list args; + va_start(args, pcFormat); + Log(static_cast(LogLevel::LogLevel_Verbose), pcFormat, args); + va_end(args); +} + +void LoggerGoogle :: Log(const int iLogLevel, const char * pcFormat, va_list args) +{ + char sBuf[1024] = {0}; + vsnprintf(sBuf, sizeof(sBuf), pcFormat, args); + + if (iLogLevel == static_cast(LogLevel::LogLevel_Error)) + { + LOG(ERROR) << sBuf; + } + else if (iLogLevel == static_cast(LogLevel::LogLevel_Warning)) + { + LOG(WARNING) << sBuf; + } + else if (iLogLevel == static_cast(LogLevel::LogLevel_Info)) + { + LOG(INFO) << sBuf; + } + else if (iLogLevel == static_cast(LogLevel::LogLevel_Verbose)) + { + LOG(INFO) << sBuf; + } +} + +} + diff --git a/plugin/logger_google/logger_google_impl.cpp b/plugin/logger_google/logger_google_impl.cpp new file mode 100644 index 000000000..04585ae5b --- /dev/null +++ b/plugin/logger_google/logger_google_impl.cpp @@ -0,0 +1,111 @@ +/* + Copyright (c) 2016 Tencent. See the AUTHORS file for names + of contributors. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "logger_google_impl.h" +#include + +#include +#include +#include + +using namespace std; + +namespace phxpaxos +{ + +LoggerGoogleImpl :: LoggerGoogleImpl(const std::string & sModuleName, const std::string & sLogPath, const int iLogLevel) +{ + google::InitGoogleLogging(sModuleName.c_str()); + FLAGS_log_dir = sLogPath; + FLAGS_stderrthreshold = google :: FATAL; + switch( iLogLevel ) + { + case 1: + FLAGS_minloglevel = google::ERROR; + break; + case 2: + FLAGS_minloglevel = google::WARNING; + break; + case 3: + FLAGS_minloglevel = google::INFO; + break; + } + + LogError("%s", "init_glog_warning_file"); + LogWarning("%s", "init_glog_error_file"); + LogInfo("%s", "init_glog_error_file"); + LogVerbose("%s", "init_glog_info_file"); +} + +LoggerGoogleImpl :: ~LoggerGoogleImpl() +{ +} + +void LoggerGoogleImpl :: LogError(const char * pcFormat, ...) +{ + char sBuf[1024] = {0}; + string newFormat = "\033[41;37m " + string(pcFormat) + " \033[0m"; + va_list args; + va_start(args, pcFormat); + vsnprintf(sBuf, sizeof(sBuf), newFormat.c_str(), args); + va_end(args); + + LOG(ERROR) << sBuf; +} + +void LoggerGoogleImpl :: LogWarning(const char * pcFormat, ...) +{ + char sBuf[1024] = {0}; + string newFormat = "\033[44;37m " + string(pcFormat) + " \033[0m"; + va_list args; + va_start(args, pcFormat); + vsnprintf(sBuf, sizeof(sBuf), newFormat.c_str(), args); + va_end(args); + + LOG(WARNING) << sBuf; +} + +void LoggerGoogleImpl :: LogInfo(const char * pcFormat, ...) +{ + char sBuf[1024] = {0}; + string newFormat = "\033[45;37m " + string(pcFormat) + " \033[0m"; + va_list args; + va_start(args, pcFormat); + vsnprintf(sBuf, sizeof(sBuf), newFormat.c_str(), args); + va_end(args); + + LOG(INFO) << sBuf; +} + +void LoggerGoogleImpl :: LogVerbose(const char * pcFormat, ...) +{ + char sBuf[1024] = {0}; + va_list args; + va_start(args, pcFormat); + vsnprintf(sBuf, sizeof(sBuf), pcFormat, args); + va_end(args); + + LOG(INFO) << sBuf; +} + +} + + diff --git a/plugin/logger_google/logger_google_impl.h b/plugin/logger_google/logger_google_impl.h new file mode 100644 index 000000000..a83665554 --- /dev/null +++ b/plugin/logger_google/logger_google_impl.h @@ -0,0 +1,46 @@ +/* + Copyright (c) 2016 Tencent. See the AUTHORS file for names + of contributors. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#pragma once + +#include "phxpaxos/log.h" +#include "phxpaxos_plugin/logger_google.h" +#include + +namespace phxpaxos +{ + +class LoggerGoogleImpl : public LoggerGoogle +{ +public: + LoggerGoogleImpl(const std::string & sModuleName, const std::string & sLogPath, const int iLogLevel); + ~LoggerGoogleImpl(); + + void LogError(const char * pcFormat, ...); + + void LogWarning(const char * pcFormat, ...); + + void LogInfo(const char * pcFormat, ...); + + void LogVerbose(const char * pcFormat, ...); +}; + +} diff --git a/plugin/monitor/Makefile.define b/plugin/monitor/Makefile.define new file mode 100644 index 000000000..60844d8b7 --- /dev/null +++ b/plugin/monitor/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libmonitor.a + +MONITOR_OBJ=monitor.o monitor_bp.o + +MONITOR_LIB=monitor plugin/include:include + +MONITOR_SYS_LIB=$(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread + +MONITOR_INCS=$(SRC_BASE_PATH)/plugin/monitor $(PHXPAXOS_INCLUDE_PATH) $(LEVELDB_INCLUDE_PATH) $(PROTOBUF_INCLUDE_PATH) + +MONITOR_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/plugin/monitor/monitor.cpp b/plugin/monitor/monitor.cpp new file mode 100644 index 000000000..b9c1f5bd0 --- /dev/null +++ b/plugin/monitor/monitor.cpp @@ -0,0 +1,45 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "phxpaxos_plugin/monitor.h" +#include "monitor_bp.h" + +namespace phxpaxos +{ + +MonitorConfig :: MonitorConfig() + : iOssAttrID(0), iUseTimeOssAttrID(0) +{ +} + +phxpaxos::Breakpoint * Monitor :: GetBreakpoint(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) +{ + if (pIDKeyOssFunc == nullptr) + { + return nullptr; + } + + MonitorBP * poMonitorBP = new MonitorBP(oMonitorConfig, pIDKeyOssFunc); + return poMonitorBP; +} + +} + diff --git a/plugin/monitor/monitor_bp.cpp b/plugin/monitor/monitor_bp.cpp new file mode 100644 index 000000000..0787c1ebc --- /dev/null +++ b/plugin/monitor/monitor_bp.cpp @@ -0,0 +1,732 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "monitor_bp.h" + +namespace phxpaxos +{ + +int GetKeyByUseTimeMs(const int iUseTimeMs) +{ + if (iUseTimeMs <= 10) + { + return 1; + } + else if (iUseTimeMs <= 30) + { + return 2; + } + else if (iUseTimeMs < 100) + { + return 3; + } + else if (iUseTimeMs <= 500) + { + return 4; + } + else if (iUseTimeMs <= 2000) + { + return 5; + } + else if (iUseTimeMs <= 5000) + { + return 6; + } + else if (iUseTimeMs <= 30000) + { + return 7; + } + else + { + return 8; + } +} + +void MonProposerBP :: NewProposal(const std::string & sValue) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 0, 1); + + if (sValue.size() < 1024) + { + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 103, 1); + } + else if (sValue.size() < 5120) + { + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 104, 1); + } + else if (sValue.size() < 20480) + { + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 105, 1); + } + else if (sValue.size() < 102400) + { + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 106, 1); + } + else if (sValue.size() < 512000) + { + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 107, 1); + } + else + { + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 108, 1); + } +} + +void MonProposerBP :: NewProposalSkipPrepare() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 1, 1); +} + +void MonProposerBP :: Prepare() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 2, 1); +} + +void MonProposerBP :: OnPrepareReply() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 3, 1); +} + +void MonProposerBP :: OnPrepareReplyButNotPreparing() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 4, 1); +} + +void MonProposerBP :: OnPrepareReplyNotSameProposalIDMsg() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 5, 1); +} + +void MonProposerBP :: PreparePass(const int iUseTimeMs) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 6, 1); + + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 18, iUseTimeMs); + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 18 + GetKeyByUseTimeMs(iUseTimeMs), 1); +} + +void MonProposerBP :: PrepareNotPass() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 7, 1); +} + +void MonProposerBP :: Accept() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 8, 1); +} + +void MonProposerBP :: OnAcceptReply() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 9, 1); +} + +void MonProposerBP :: OnAcceptReplyButNotAccepting() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 10, 1); +} + +void MonProposerBP :: OnAcceptReplyNotSameProposalIDMsg() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 11, 1); +} + +void MonProposerBP :: AcceptPass(const int iUseTimeMs) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 12, 1); + + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 27, iUseTimeMs); + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 27 + GetKeyByUseTimeMs(iUseTimeMs), 1); +} + +void MonProposerBP :: AcceptNotPass() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 13, 1); +} + +void MonProposerBP :: PrepareTimeout() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 14, 1); +} + +void MonProposerBP :: AcceptTimeout() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 15, 1); +} + +//////////////////////////////////////////////////////////// + +void MonAcceptorBP :: OnPrepare() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 16, 1); +} + +void MonAcceptorBP :: OnPreparePass() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 17, 1); +} + +void MonAcceptorBP :: OnPreparePersistFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 18, 1); +} + +void MonAcceptorBP :: OnPrepareReject() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 19, 1); +} + +void MonAcceptorBP :: OnAccept() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 20, 1); +} + +void MonAcceptorBP :: OnAcceptPass() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 21, 1); +} + +void MonAcceptorBP :: OnAcceptPersistFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 22, 1); +} + +void MonAcceptorBP :: OnAcceptReject() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 23, 1); +} + +//////////////////////////////////////////////////// +void MonLearnerBP :: AskforLearn() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 24, 1); +} + +void MonLearnerBP :: OnAskforLearn() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 25, 1); +} + +void MonLearnerBP :: OnAskforLearnGetLockFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 26, 1); +} + +void MonLearnerBP :: SendNowInstanceID() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 27, 1); +} + +void MonLearnerBP :: OnSendNowInstanceID() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 28, 1); +} + +void MonLearnerBP :: ComfirmAskForLearn() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 29, 1); +} + +void MonLearnerBP :: OnComfirmAskForLearn() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 30, 1); +} + +void MonLearnerBP :: OnComfirmAskForLearnGetLockFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 31, 1); +} + +void MonLearnerBP :: SendLearnValue() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 32, 1); +} + +void MonLearnerBP :: OnSendLearnValue() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 33, 1); +} + +void MonLearnerBP :: SendLearnValue_Ack() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 34, 1); +} + +void MonLearnerBP :: OnSendLearnValue_Ack() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 35, 1); +} + +void MonLearnerBP :: ProposerSendSuccess() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 36, 1); +} + +void MonLearnerBP :: OnProposerSendSuccess() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 37, 1); +} + +void MonLearnerBP :: OnProposerSendSuccessNotAcceptYet() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 38, 1); +} + +void MonLearnerBP :: OnProposerSendSuccessBallotNotSame() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 39, 1); +} + +void MonLearnerBP :: OnProposerSendSuccessSuccessLearn() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 40, 1); +} + +void MonLearnerBP :: SenderAckTimeout() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 41, 1); +} + +void MonLearnerBP :: SenderAckDelay() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 42, 1); +} + +void MonLearnerBP :: SenderSendOnePaxosLog() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 43, 1); +} + +/////////////////////////////////////////////////////////// +void MonInstanceBP :: NewInstance() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 44, 1); +} + +void MonInstanceBP :: SendMessage() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 45, 1); +} + +void MonInstanceBP :: BroadcastMessage() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 46, 1); +} + +void MonInstanceBP :: OnNewValueCommitTimeout() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 47, 1); +} + +void MonInstanceBP :: OnReceive() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 48, 1); +} + +void MonInstanceBP :: OnReceiveParseError() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 49, 1); +} + +void MonInstanceBP :: OnReceivePaxosMsg() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 50, 1); +} + +void MonInstanceBP :: OnReceivePaxosMsgNodeIDNotValid() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 51, 1); +} + +void MonInstanceBP :: OnReceivePaxosMsgTypeNotValid() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 52, 1); +} + +void MonInstanceBP :: OnReceivePaxosProposerMsgInotsame() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 53, 1); +} + +void MonInstanceBP :: OnReceivePaxosAcceptorMsgInotsame() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 54, 1); +} + +void MonInstanceBP :: OnReceivePaxosAcceptorMsgAddRetry() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 55, 1); +} + +void MonInstanceBP :: OnInstanceLearned() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 56, 1); +} + +void MonInstanceBP :: OnInstanceLearnedNotMyCommit() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 57, 1); +} + +void MonInstanceBP :: OnInstanceLearnedIsMyCommit(const int iUseTimeMs) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 58, 1); + + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 0, iUseTimeMs); + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, GetKeyByUseTimeMs(iUseTimeMs), 1); +} + +void MonInstanceBP :: OnInstanceLearnedSMExcuteFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 59, 1); +} + +void MonInstanceBP :: ChecksumLogicFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 60, 1); +} + +///////////////////////////////////////////////////////// + +void MonCommiterBP :: NewValue() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 61, 1); +} + +void MonCommiterBP :: NewValueConflict() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 62, 1); +} + +void MonCommiterBP :: NewValueGetLockTimeout() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 63, 1); +} + +void MonCommiterBP :: NewValueGetLockOK(const int iUseTimeMs) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 64, 1); +} + +void MonCommiterBP :: NewValueCommitOK(const int iUseTimeMs) +{ +} + +void MonCommiterBP :: NewValueCommitFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 65, 1); +} + +////////////////////////////////////////////////////////// + + +void MonIOLoopBP :: OneLoop() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 66, 1); +} + +void MonIOLoopBP :: EnqueueMsg() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 67, 1); +} + +void MonIOLoopBP :: EnqueueMsgRejectByFullQueue() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 68, 1); +} + +void MonIOLoopBP :: EnqueueRetryMsg() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 69, 1); +} + +void MonIOLoopBP :: EnqueueRetryMsgRejectByFullQueue() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 70, 1); +} + +void MonIOLoopBP :: OutQueueMsg() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 71, 1); +} + +void MonIOLoopBP :: DealWithRetryMsg() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 72, 1); +} + +//////////////////////////////////////////////////////////// + +void MonNetworkBP :: TcpEpollLoop() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 73, 1); +} + +void MonNetworkBP :: TcpOnError() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 74, 1); +} + +void MonNetworkBP :: TcpAcceptFd() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 75, 1); +} + +void MonNetworkBP :: TcpQueueFull() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 76, 1); +} + +void MonNetworkBP :: TcpReadOneMessageOk(const int iLen) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 77, 1); + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 78, iLen); +} + +void MonNetworkBP :: TcpOnReadMessageLenError() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 79, 1); +} + +void MonNetworkBP :: TcpReconnect() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 80, 1); +} + +void MonNetworkBP :: SendRejectByTooLargeSize() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 81, 1); +} + +void MonNetworkBP :: Send(const std::string & sMessage) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 82, 1); + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 83, (int)sMessage.size()); +} + +void MonNetworkBP :: SendTcp(const std::string & sMessage) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 84, 1); + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 85, (int)sMessage.size()); +} + +void MonNetworkBP :: SendUdp(const std::string & sMessage) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 86, 1); + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 87, (int)sMessage.size()); +} + +void MonNetworkBP :: SendMessageNodeIDNotFound() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 88, 1); +} + +void MonNetworkBP :: UDPReceive(const int iRecvLen) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 89, 1); + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 90, iRecvLen); +} + +void MonNetworkBP :: UDPRealSend(const std::string & sMessage) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 91, 1); + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 92, (int)sMessage.size()); +} + +void MonNetworkBP :: UDPQueueFull() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 93, 1); +} + +/////////////////////////////////////////////////////////////// + +void MonLogStorageBP :: LevelDBGetNotExist() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 94, 1); +} + +void MonLogStorageBP :: LevelDBGetFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 95, 1); +} + +void MonLogStorageBP :: FileIDToValueFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 96, 1); +} + +void MonLogStorageBP :: ValueToFileIDFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 97, 1); +} + +void MonLogStorageBP :: LevelDBPutFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 98, 1); +} + +void MonLogStorageBP :: LevelDBPutOK(const int iUseTimeMs) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 36, iUseTimeMs); + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, GetKeyByUseTimeMs(iUseTimeMs) + 36, 1); +} + +void MonLogStorageBP :: AppendDataFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 99, 1); +} + +void MonLogStorageBP :: AppendDataOK(const int iWriteLen, const int iUseTimeMs) +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 100, 1); + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 101, iWriteLen); + + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 9, iUseTimeMs); + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 9 + GetKeyByUseTimeMs(iUseTimeMs), 1); +} + +void MonLogStorageBP :: GetFileChecksumNotEquel() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iOssAttrID, 102, 1); +} + +//////////////////////////////////////////////////////////////// + + +void MonAlgorithmBaseBP :: UnPackHeaderLenTooLong() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 45, 1); +} + +void MonAlgorithmBaseBP :: UnPackChecksumNotSame() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 46, 1); +} + +void MonAlgorithmBaseBP :: HeaderGidNotSame() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 47, 1); +} + +//////////////////////////////////////////////////////////////// + +void MonCheckpointBP :: NeedAskforCheckpoint() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 48, 1); +} + +void MonCheckpointBP :: SendCheckpointOneBlock() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 49, 1); +} + +void MonCheckpointBP :: OnSendCheckpointOneBlock() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 50, 1); +} + +void MonCheckpointBP :: SendCheckpointBegin() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 51, 1); +} + +void MonCheckpointBP :: SendCheckpointEnd() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 52, 1); +} + +void MonCheckpointBP :: ReceiveCheckpointDone() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 53, 1); +} + +void MonCheckpointBP :: ReceiveCheckpointAndLoadFail() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 54, 1); +} + +void MonCheckpointBP :: ReceiveCheckpointAndLoadSucc() +{ + m_pIDKeyOssFunc(m_oMonitorConfig.iUseTimeOssAttrID, 55, 1); +} + +///////////////////////////////////////////////////////////////// + +MonitorBP :: MonitorBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) : + m_oProposerBP(oMonitorConfig, pIDKeyOssFunc), m_oAcceptorBP(oMonitorConfig, pIDKeyOssFunc), + m_oLearnerBP(oMonitorConfig, pIDKeyOssFunc), m_oInstanceBP(oMonitorConfig, pIDKeyOssFunc), + m_oCommiterBP(oMonitorConfig, pIDKeyOssFunc), m_oIOLoopBP(oMonitorConfig, pIDKeyOssFunc), + m_oNetworkBP(oMonitorConfig, pIDKeyOssFunc), m_oLogStorageBP(oMonitorConfig, pIDKeyOssFunc), + m_oAlgorithmBaseBP(oMonitorConfig, pIDKeyOssFunc), m_oCheckpointBP(oMonitorConfig, pIDKeyOssFunc) +{ +} + +ProposerBP * MonitorBP :: GetProposerBP() +{ + return &m_oProposerBP; +} + +AcceptorBP * MonitorBP :: GetAcceptorBP() +{ + return &m_oAcceptorBP; +} + +LearnerBP * MonitorBP :: GetLearnerBP() +{ + return &m_oLearnerBP; +} + +InstanceBP * MonitorBP :: GetInstanceBP() +{ + return &m_oInstanceBP; +} + +CommiterBP * MonitorBP :: GetCommiterBP() +{ + return &m_oCommiterBP; +} + +IOLoopBP * MonitorBP :: GetIOLoopBP() +{ + return &m_oIOLoopBP; +} + +NetworkBP * MonitorBP :: GetNetworkBP() +{ + return &m_oNetworkBP; +} + +LogStorageBP * MonitorBP :: GetLogStorageBP() +{ + return &m_oLogStorageBP; +} + +AlgorithmBaseBP * MonitorBP :: GetAlgorithmBaseBP() +{ + return &m_oAlgorithmBaseBP; +} + +CheckpointBP * MonitorBP :: GetCheckpointBP() +{ + return &m_oCheckpointBP; +} + +} + diff --git a/plugin/monitor/monitor_bp.h b/plugin/monitor/monitor_bp.h new file mode 100644 index 000000000..d531fb965 --- /dev/null +++ b/plugin/monitor/monitor_bp.h @@ -0,0 +1,297 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/breakpoint.h" +#include +#include "phxpaxos_plugin/monitor.h" + +namespace phxpaxos +{ + +class MonProposerBP : public ProposerBP +{ +public: + MonProposerBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) + : m_oMonitorConfig(oMonitorConfig), m_pIDKeyOssFunc(pIDKeyOssFunc) { } + void NewProposal(const std::string & sValue); + void NewProposalSkipPrepare(); + void Prepare(); + void OnPrepareReply(); + void OnPrepareReplyButNotPreparing(); + void OnPrepareReplyNotSameProposalIDMsg(); + void PreparePass(const int iUseTimeMs); + void PrepareNotPass(); + void Accept(); + void OnAcceptReply(); + void OnAcceptReplyButNotAccepting(); + void OnAcceptReplyNotSameProposalIDMsg(); + void AcceptPass(const int iUseTimeMs); + void AcceptNotPass(); + void PrepareTimeout(); + void AcceptTimeout(); + +private: + MonitorConfig m_oMonitorConfig; + IDKeyOssFunc m_pIDKeyOssFunc; +}; + +class MonAcceptorBP : public AcceptorBP +{ +public: + MonAcceptorBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) + : m_oMonitorConfig(oMonitorConfig), m_pIDKeyOssFunc(pIDKeyOssFunc) { } + void OnPrepare(); + void OnPreparePass(); + void OnPreparePersistFail(); + void OnPrepareReject(); + void OnAccept(); + void OnAcceptPass(); + void OnAcceptPersistFail(); + void OnAcceptReject(); + +private: + MonitorConfig m_oMonitorConfig; + IDKeyOssFunc m_pIDKeyOssFunc; +}; + +class MonLearnerBP : public LearnerBP +{ +public: + MonLearnerBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) + : m_oMonitorConfig(oMonitorConfig), m_pIDKeyOssFunc(pIDKeyOssFunc) { } + void AskforLearn(); + void OnAskforLearn(); + void OnAskforLearnGetLockFail(); + void SendNowInstanceID(); + void OnSendNowInstanceID(); + void ComfirmAskForLearn(); + void OnComfirmAskForLearn(); + void OnComfirmAskForLearnGetLockFail(); + void SendLearnValue(); + void OnSendLearnValue(); + void SendLearnValue_Ack(); + void OnSendLearnValue_Ack(); + void ProposerSendSuccess(); + void OnProposerSendSuccess(); + void OnProposerSendSuccessNotAcceptYet(); + void OnProposerSendSuccessBallotNotSame(); + void OnProposerSendSuccessSuccessLearn(); + void SenderAckTimeout(); + void SenderAckDelay(); + void SenderSendOnePaxosLog(); + +private: + MonitorConfig m_oMonitorConfig; + IDKeyOssFunc m_pIDKeyOssFunc; +}; + +class MonInstanceBP : public InstanceBP +{ +public: + MonInstanceBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) + : m_oMonitorConfig(oMonitorConfig), m_pIDKeyOssFunc(pIDKeyOssFunc) { } + void NewInstance(); + void SendMessage(); + void BroadcastMessage(); + void OnNewValueCommitTimeout(); + void OnReceive(); + void OnReceiveParseError(); + void OnReceivePaxosMsg(); + void OnReceivePaxosMsgNodeIDNotValid(); + void OnReceivePaxosMsgTypeNotValid(); + void OnReceivePaxosProposerMsgInotsame(); + void OnReceivePaxosAcceptorMsgInotsame(); + void OnReceivePaxosAcceptorMsgAddRetry(); + void OnInstanceLearned(); + void OnInstanceLearnedNotMyCommit(); + void OnInstanceLearnedIsMyCommit(const int iUseTimeMs); + void OnInstanceLearnedSMExcuteFail(); + void ChecksumLogicFail(); + +private: + MonitorConfig m_oMonitorConfig; + IDKeyOssFunc m_pIDKeyOssFunc; +}; + +class MonCommiterBP : public CommiterBP +{ +public: + MonCommiterBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) + : m_oMonitorConfig(oMonitorConfig), m_pIDKeyOssFunc(pIDKeyOssFunc) { } + void NewValue(); + void NewValueConflict(); + void NewValueGetLockTimeout(); + void NewValueGetLockOK(const int iUseTimeMs); + void NewValueCommitOK(const int iUseTimeMs); + void NewValueCommitFail(); + +private: + MonitorConfig m_oMonitorConfig; + IDKeyOssFunc m_pIDKeyOssFunc; +}; + +class MonIOLoopBP : public IOLoopBP +{ +public: + MonIOLoopBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) + : m_oMonitorConfig(oMonitorConfig), m_pIDKeyOssFunc(pIDKeyOssFunc) { } + void OneLoop(); + void EnqueueMsg(); + void EnqueueMsgRejectByFullQueue(); + void EnqueueRetryMsg(); + void EnqueueRetryMsgRejectByFullQueue(); + void OutQueueMsg(); + void DealWithRetryMsg(); + +private: + MonitorConfig m_oMonitorConfig; + IDKeyOssFunc m_pIDKeyOssFunc; +}; + +class MonNetworkBP : public NetworkBP +{ +public: + MonNetworkBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) + : m_oMonitorConfig(oMonitorConfig), m_pIDKeyOssFunc(pIDKeyOssFunc) { } + void TcpEpollLoop(); + void TcpOnError(); + void TcpAcceptFd(); + void TcpQueueFull(); + void TcpReadOneMessageOk(const int iLen); + void TcpOnReadMessageLenError(); + void TcpReconnect(); + void SendRejectByTooLargeSize(); + void Send(const std::string & sMessage); + void SendTcp(const std::string & sMessage); + void SendUdp(const std::string & sMessage); + void SendMessageNodeIDNotFound(); + void UDPReceive(const int iRecvLen); + void UDPRealSend(const std::string & sMessage); + void UDPQueueFull(); + +private: + MonitorConfig m_oMonitorConfig; + IDKeyOssFunc m_pIDKeyOssFunc; +}; + +class MonLogStorageBP : public LogStorageBP +{ +public: + MonLogStorageBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) + : m_oMonitorConfig(oMonitorConfig), m_pIDKeyOssFunc(pIDKeyOssFunc) { } + void LevelDBGetNotExist(); + void LevelDBGetFail(); + void FileIDToValueFail(); + void ValueToFileIDFail(); + void LevelDBPutFail(); + void LevelDBPutOK(const int iUseTimeMs); + void AppendDataFail(); + void AppendDataOK(const int iWriteLen, const int iUseTimeMs); + void GetFileChecksumNotEquel(); + +private: + MonitorConfig m_oMonitorConfig; + IDKeyOssFunc m_pIDKeyOssFunc; +}; + +/////////////////////////////////////////////////////////////// + +class MonAlgorithmBaseBP : public AlgorithmBaseBP +{ +public: + MonAlgorithmBaseBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) + : m_oMonitorConfig(oMonitorConfig), m_pIDKeyOssFunc(pIDKeyOssFunc) { } + + virtual void UnPackHeaderLenTooLong(); + virtual void UnPackChecksumNotSame(); + virtual void HeaderGidNotSame(); + +private: + MonitorConfig m_oMonitorConfig; + IDKeyOssFunc m_pIDKeyOssFunc; +}; + +/////////////////////////////////////////////////////////////// + +class MonCheckpointBP : public CheckpointBP +{ +public: + MonCheckpointBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc) + : m_oMonitorConfig(oMonitorConfig), m_pIDKeyOssFunc(pIDKeyOssFunc) { } + + virtual void NeedAskforCheckpoint(); + virtual void SendCheckpointOneBlock(); + virtual void OnSendCheckpointOneBlock(); + virtual void SendCheckpointBegin(); + virtual void SendCheckpointEnd(); + virtual void ReceiveCheckpointDone(); + virtual void ReceiveCheckpointAndLoadFail(); + virtual void ReceiveCheckpointAndLoadSucc(); + +private: + MonitorConfig m_oMonitorConfig; + IDKeyOssFunc m_pIDKeyOssFunc; +}; + +/////////////////////////////////////////////////////////////// + + +class MonitorBP : public Breakpoint +{ +public: + MonitorBP(const MonitorConfig & oMonitorConfig, IDKeyOssFunc pIDKeyOssFunc); + + ProposerBP * GetProposerBP(); + + AcceptorBP * GetAcceptorBP(); + + LearnerBP * GetLearnerBP(); + + InstanceBP * GetInstanceBP(); + + CommiterBP * GetCommiterBP(); + + IOLoopBP * GetIOLoopBP(); + + NetworkBP * GetNetworkBP(); + + LogStorageBP * GetLogStorageBP(); + + AlgorithmBaseBP * GetAlgorithmBaseBP(); + + CheckpointBP * GetCheckpointBP(); + +public: + MonProposerBP m_oProposerBP; + MonAcceptorBP m_oAcceptorBP; + MonLearnerBP m_oLearnerBP; + MonInstanceBP m_oInstanceBP; + MonCommiterBP m_oCommiterBP; + MonIOLoopBP m_oIOLoopBP; + MonNetworkBP m_oNetworkBP; + MonLogStorageBP m_oLogStorageBP; + MonAlgorithmBaseBP m_oAlgorithmBaseBP; + MonCheckpointBP m_oCheckpointBP; +}; + +} diff --git a/sample/phxecho/Makefile.define b/sample/phxecho/Makefile.define new file mode 100644 index 000000000..479cc5758 --- /dev/null +++ b/sample/phxecho/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=phxecho + +PHXECHO_OBJ=echo_sm.o echo_server.o main.o + +PHXECHO_LIB= + +PHXECHO_SYS_LIB=$(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread $(PHXPAXOS_LIB_PATH)/libphxpaxos_plugin.a $(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread $(GLOG_LIB_PATH)/libglog.a $(GLOG_LIB_PATH)/libglog.a -lpthread + +PHXECHO_INCS=$(SRC_BASE_PATH)/sample/phxecho $(PHXPAXOS_PLUGIN_PATH) $(PHXPAXOS_INCLUDE_PATH) $(LEVELDB_INCLUDE_PATH) $(PROTOBUF_INCLUDE_PATH) + +PHXECHO_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/sample/phxecho/README b/sample/phxecho/README new file mode 100644 index 000000000..16a4dfb11 --- /dev/null +++ b/sample/phxecho/README @@ -0,0 +1,9 @@ +This is not a real server. just to tell you how to use phxpaxos. + +The echo command will replicate to other echo_server by phxpaxos. + +The suggest start shell write on echo.sh. you can run three echo_server to test phxpaxos. + +Echo_server will create a workspace dir on ./logpath_ip_port, data generate by phxpaxos will write on this path. + +Have fun :). diff --git a/sample/phxecho/echo_server.cpp b/sample/phxecho/echo_server.cpp new file mode 100644 index 000000000..32688e18a --- /dev/null +++ b/sample/phxecho/echo_server.cpp @@ -0,0 +1,139 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "echo_server.h" +#include +#include +#include +#include +#include +#include + +using namespace phxpaxos; +using namespace std; + +namespace phxecho +{ + +PhxEchoServer :: PhxEchoServer(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList) + : m_oMyNode(oMyNode), m_vecNodeList(vecNodeList), m_poPaxosNode(nullptr) +{ +} + +PhxEchoServer :: ~PhxEchoServer() +{ + delete m_poPaxosNode; +} + +int PhxEchoServer :: MakeLogStoragePath(std::string & sLogStoragePath) +{ + char sTmp[128] = {0}; + snprintf(sTmp, sizeof(sTmp), "./logpath_%s_%d", m_oMyNode.GetIP().c_str(), m_oMyNode.GetPort()); + + sLogStoragePath = string(sTmp); + + if (access(sLogStoragePath.c_str(), F_OK) == -1) + { + if (mkdir(sLogStoragePath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) + { + printf("Create dir fail, path %s\n", sLogStoragePath.c_str()); + return -1; + } + } + + return 0; +} + +int PhxEchoServer :: RunPaxos() +{ + Options oOptions; + + int ret = MakeLogStoragePath(oOptions.sLogStoragePath); + if (ret != 0) + { + return ret; + } + + //this groupcount means run paxos group count. + //every paxos group is independent, there are no any communicate between any 2 paxos group. + oOptions.iGroupCount = 1; + + oOptions.oMyNode = m_oMyNode; + oOptions.vecNodeInfoList = m_vecNodeList; + + GroupSMInfo oSMInfo; + oSMInfo.iGroupIdx = 0; + //one paxos group can have multi state machine. + oSMInfo.vecSMList.push_back(&m_oEchoSM); + oOptions.vecGroupSMInfoList.push_back(oSMInfo); + + //use logger_google to print log + LogFunc pLogFunc; + ret = LoggerGoogle :: GetLogger("phxecho", "./log", 3, pLogFunc); + if (ret != 0) + { + printf("get logger_google fail, ret %d\n", ret); + return ret; + } + + //set logger + oOptions.pLogFunc = pLogFunc; + + ret = Node::RunNode(oOptions, m_poPaxosNode); + if (ret != 0) + { + printf("run paxos fail, ret %d\n", ret); + return ret; + } + + printf("run paxos ok\n"); + return 0; +} + +int PhxEchoServer :: Echo(const std::string & sEchoReqValue, std::string & sEchoRespValue) +{ + SMCtx oCtx; + PhxEchoSMCtx oEchoSMCtx; + //smid must same to PhxEchoSM.SMID(). + oCtx.m_iSMID = 1; + oCtx.m_pCtx = (void *)&oEchoSMCtx; + + uint64_t llInstanceID = 0; + int ret = m_poPaxosNode->Propose(0, sEchoReqValue, llInstanceID, &oCtx); + if (ret != 0) + { + printf("paxos propose fail, ret %d\n", ret); + return ret; + } + + if (oEchoSMCtx.iExcuteRet != 0) + { + printf("echo sm excute fail, excuteret %d\n", oEchoSMCtx.iExcuteRet); + return oEchoSMCtx.iExcuteRet; + } + + sEchoRespValue = oEchoSMCtx.sEchoRespValue.c_str(); + + return 0; +} + +} + diff --git a/sample/phxecho/echo_server.h b/sample/phxecho/echo_server.h new file mode 100644 index 000000000..0587f6e17 --- /dev/null +++ b/sample/phxecho/echo_server.h @@ -0,0 +1,56 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/node.h" +#include "echo_sm.h" +#include +#include +#include "phxpaxos_plugin/logger_google.h" + +namespace phxecho +{ + +class PhxEchoServer +{ +public: + PhxEchoServer(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList); + ~PhxEchoServer(); + + int RunPaxos(); + + int Echo(const std::string & sEchoReqValue, std::string & sEchoRespValue); + +private: + int MakeLogStoragePath(std::string & sLogStoragePath); + +private: + phxpaxos::NodeInfo m_oMyNode; + phxpaxos::NodeInfoList m_vecNodeList; + + phxpaxos::Node * m_poPaxosNode; + PhxEchoSM m_oEchoSM; +}; + +} + + diff --git a/sample/phxecho/echo_sm.cpp b/sample/phxecho/echo_sm.cpp new file mode 100644 index 000000000..7e7394fc5 --- /dev/null +++ b/sample/phxecho/echo_sm.cpp @@ -0,0 +1,51 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "echo_sm.h" + +using namespace phxpaxos; + +namespace phxecho +{ + +PhxEchoSM :: PhxEchoSM() +{ +} + +bool PhxEchoSM :: Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, SMCtx * poSMCtx) +{ + printf("[SM Execute] ok, smid %d instanceid %lu value %s\n", + SMID(), llInstanceID, sPaxosValue.c_str()); + + //only commiter node have SMCtx. + if (poSMCtx != nullptr && poSMCtx->m_pCtx != nullptr) + { + PhxEchoSMCtx * poPhxEchoSMCtx = (PhxEchoSMCtx *)poSMCtx->m_pCtx; + poPhxEchoSMCtx->iExcuteRet = 0; + poPhxEchoSMCtx->sEchoRespValue = sPaxosValue; + } + + return true; +} + +} + diff --git a/sample/phxecho/echo_sm.h b/sample/phxecho/echo_sm.h new file mode 100644 index 000000000..688431856 --- /dev/null +++ b/sample/phxecho/echo_sm.h @@ -0,0 +1,55 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/sm.h" +#include "phxpaxos/options.h" +#include +#include + +namespace phxecho +{ + +class PhxEchoSMCtx +{ +public: + int iExcuteRet; + std::string sEchoRespValue; + + PhxEchoSMCtx() + { + iExcuteRet = -1; + } +}; + +class PhxEchoSM : public phxpaxos::StateMachine +{ +public: + PhxEchoSM(); + + bool Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, phxpaxos::SMCtx * poSMCtx); + + const int SMID() const { return 1; } +}; + +} diff --git a/sample/phxecho/main.cpp b/sample/phxecho/main.cpp new file mode 100644 index 000000000..f0fc209e9 --- /dev/null +++ b/sample/phxecho/main.cpp @@ -0,0 +1,134 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "echo_server.h" +#include +#include +#include +#include +#include +#include "phxpaxos/options.h" + +using namespace phxecho; +using namespace phxpaxos; +using namespace std; + +int parse_ipport(const char * pcStr, NodeInfo & oNodeInfo) +{ + char sIP[32] = {0}; + int iPort = -1; + + int count = sscanf(pcStr, "%[^':']:%d", sIP, &iPort); + if (count != 2) + { + return -1; + } + + oNodeInfo.SetIPPort(sIP, iPort); + + return 0; +} + +int parse_ipport_list(const char * pcStr, NodeInfoList & vecNodeInfoList) +{ + string sTmpStr; + int iStrLen = strlen(pcStr); + + for (int i = 0; i < iStrLen; i++) + { + if (pcStr[i] == ',' || i == iStrLen - 1) + { + if (i == iStrLen - 1 && pcStr[i] != ',') + { + sTmpStr += pcStr[i]; + } + + NodeInfo oNodeInfo; + int ret = parse_ipport(sTmpStr.c_str(), oNodeInfo); + if (ret != 0) + { + return ret; + } + + vecNodeInfoList.push_back(oNodeInfo); + + sTmpStr = ""; + } + else + { + sTmpStr += pcStr[i]; + } + } + + return 0; +} + +int main(int argc, char ** argv) +{ + if (argc < 3) + { + printf("%s \n", argv[0]); + return -1; + } + + NodeInfo oMyNode; + if (parse_ipport(argv[1], oMyNode) != 0) + { + printf("parse myip:myport fail\n"); + return -1; + } + + NodeInfoList vecNodeInfoList; + if (parse_ipport_list(argv[2], vecNodeInfoList) != 0) + { + printf("parse ip/port list fail\n"); + return -1; + } + + PhxEchoServer oEchoServer(oMyNode, vecNodeInfoList); + int ret = oEchoServer.RunPaxos(); + if (ret != 0) + { + return -1; + } + + printf("echo server start, ip %s port %d\n", oMyNode.GetIP().c_str(), oMyNode.GetPort()); + + string sEchoReqValue; + while (true) + { + printf("\nplease input: \n"); + getline(cin, sEchoReqValue); + string sEchoRespValue; + ret = oEchoServer.Echo(sEchoReqValue, sEchoRespValue); + if (ret != 0) + { + printf("Echo fail, ret %d\n", ret); + } + else + { + printf("echo resp value %s\n", sEchoRespValue.c_str()); + } + } + + return 0; +} + diff --git a/sample/phxecho/run_echo.sh b/sample/phxecho/run_echo.sh new file mode 100644 index 000000000..0e20deee5 --- /dev/null +++ b/sample/phxecho/run_echo.sh @@ -0,0 +1,4 @@ +#sample +#./phxecho 127.0.0.1:11111 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113 +#./phxecho 127.0.0.1:11112 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113 +#./phxecho 127.0.0.1:11113 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113 diff --git a/sample/phxelection/Makefile.define b/sample/phxelection/Makefile.define new file mode 100644 index 000000000..ac53bf16b --- /dev/null +++ b/sample/phxelection/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=phxelection + +PHXELECTION_OBJ=election.o election_main.o + +PHXELECTION_LIB= + +PHXELECTION_SYS_LIB=$(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread $(PHXPAXOS_LIB_PATH)/libphxpaxos_plugin.a $(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread $(GLOG_LIB_PATH)/libglog.a + +PHXELECTION_INCS=$(SRC_BASE_PATH)/sample/phxelection $(PHXPAXOS_PLUGIN_PATH) $(PHXPAXOS_INCLUDE_PATH) $(LEVELDB_INCLUDE_PATH) $(PROTOBUF_INCLUDE_PATH) + +PHXELECTION_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/sample/phxelection/README b/sample/phxelection/README new file mode 100644 index 000000000..cddcd7dc5 --- /dev/null +++ b/sample/phxelection/README @@ -0,0 +1,2 @@ +This is very simple sample to use phxpaxos to election. +Check the code in election.cpp, that is really simple. diff --git a/sample/phxelection/election.cpp b/sample/phxelection/election.cpp new file mode 100644 index 000000000..43e813c3a --- /dev/null +++ b/sample/phxelection/election.cpp @@ -0,0 +1,113 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "election.h" +#include +#include +#include +#include +#include +#include + +using namespace phxpaxos; +using namespace std; + +namespace phxelection +{ + +PhxElection :: PhxElection(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList) + : m_oMyNode(oMyNode), m_vecNodeList(vecNodeList), m_poPaxosNode(nullptr) +{ +} + +PhxElection :: ~PhxElection() +{ + delete m_poPaxosNode; +} + +int PhxElection :: MakeLogStoragePath(std::string & sLogStoragePath) +{ + char sTmp[128] = {0}; + snprintf(sTmp, sizeof(sTmp), "./logpath_%s_%d", m_oMyNode.GetIP().c_str(), m_oMyNode.GetPort()); + + sLogStoragePath = string(sTmp); + + if (access(sLogStoragePath.c_str(), F_OK) == -1) + { + if (mkdir(sLogStoragePath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) + { + printf("Create dir fail, path %s\n", sLogStoragePath.c_str()); + return -1; + } + } + + return 0; +} + +int PhxElection :: RunPaxos() +{ + Options oOptions; + + int ret = MakeLogStoragePath(oOptions.sLogStoragePath); + if (ret != 0) + { + return ret; + } + + oOptions.iGroupCount = 1; + + oOptions.oMyNode = m_oMyNode; + oOptions.vecNodeInfoList = m_vecNodeList; + + //open inside master state machine + GroupSMInfo oSMInfo; + oSMInfo.iGroupIdx = 0; + oSMInfo.bIsUseMaster = true; + + oOptions.vecGroupSMInfoList.push_back(oSMInfo); + + ret = Node::RunNode(oOptions, m_poPaxosNode); + if (ret != 0) + { + printf("run paxos fail, ret %d\n", ret); + return ret; + } + + //you can change master lease in real-time. + m_poPaxosNode->SetMasterLease(0, 3000); + + printf("run paxos ok\n"); + return 0; +} + +const phxpaxos::NodeInfo PhxElection :: GetMaster() +{ + //only one group, so groupidx is 0. + return m_poPaxosNode->GetMaster(0); +} + +const bool PhxElection :: IsIMMaster() +{ + return m_poPaxosNode->IsIMMaster(0); +} + +} + diff --git a/sample/phxelection/election.h b/sample/phxelection/election.h new file mode 100644 index 000000000..13725975b --- /dev/null +++ b/sample/phxelection/election.h @@ -0,0 +1,56 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/node.h" +#include +#include +#include "phxpaxos_plugin/logger_google.h" + +namespace phxelection +{ + +class PhxElection +{ +public: + PhxElection(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList); + ~PhxElection(); + + int RunPaxos(); + + const phxpaxos::NodeInfo GetMaster(); + + const bool IsIMMaster(); + +private: + int MakeLogStoragePath(std::string & sLogStoragePath); + +private: + phxpaxos::NodeInfo m_oMyNode; + phxpaxos::NodeInfoList m_vecNodeList; + + phxpaxos::Node * m_poPaxosNode; +}; + +} + + diff --git a/sample/phxelection/election_main.cpp b/sample/phxelection/election_main.cpp new file mode 100644 index 000000000..05f67ab3b --- /dev/null +++ b/sample/phxelection/election_main.cpp @@ -0,0 +1,124 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "election.h" +#include +#include +#include +#include +#include +#include "phxpaxos/options.h" +#include + +using namespace phxelection; +using namespace phxpaxos; +using namespace std; + +int parse_ipport(const char * pcStr, NodeInfo & oNodeInfo) +{ + char sIP[32] = {0}; + int iPort = -1; + + int count = sscanf(pcStr, "%[^':']:%d", sIP, &iPort); + if (count != 2) + { + return -1; + } + + oNodeInfo.SetIPPort(sIP, iPort); + + return 0; +} + +int parse_ipport_list(const char * pcStr, NodeInfoList & vecNodeInfoList) +{ + string sTmpStr; + int iStrLen = strlen(pcStr); + + for (int i = 0; i < iStrLen; i++) + { + if (pcStr[i] == ',' || i == iStrLen - 1) + { + if (i == iStrLen - 1 && pcStr[i] != ',') + { + sTmpStr += pcStr[i]; + } + + NodeInfo oNodeInfo; + int ret = parse_ipport(sTmpStr.c_str(), oNodeInfo); + if (ret != 0) + { + return ret; + } + + vecNodeInfoList.push_back(oNodeInfo); + + sTmpStr = ""; + } + else + { + sTmpStr += pcStr[i]; + } + } + + return 0; +} + +int main(int argc, char ** argv) +{ + if (argc < 3) + { + printf("%s \n", argv[0]); + return -1; + } + + NodeInfo oMyNode; + if (parse_ipport(argv[1], oMyNode) != 0) + { + printf("parse myip:myport fail\n"); + return -1; + } + + NodeInfoList vecNodeInfoList; + if (parse_ipport_list(argv[2], vecNodeInfoList) != 0) + { + printf("parse ip/port list fail\n"); + return -1; + } + + PhxElection oElection(oMyNode, vecNodeInfoList); + int ret = oElection.RunPaxos(); + if (ret != 0) + { + return -1; + } + + while (true) + { + ::sleep(1); + NodeInfo oMasterNode = oElection.GetMaster(); + printf("master: nodeid %lu ip %s port %d\n", + oMasterNode.GetNodeID(), oMasterNode.GetIP().c_str(), oMasterNode.GetPort()); + } + + return 0; +} + diff --git a/sample/phxelection/run_election_sample.sh b/sample/phxelection/run_election_sample.sh new file mode 100644 index 000000000..acacadf61 --- /dev/null +++ b/sample/phxelection/run_election_sample.sh @@ -0,0 +1,4 @@ +#sample +#./phxelection 127.0.0.1:11111 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113 +#./phxelection 127.0.0.1:11112 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113 +#./phxelection 127.0.0.1:11113 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113 diff --git a/sample/phxkv/Makefile.define b/sample/phxkv/Makefile.define new file mode 100644 index 000000000..58e7dbf5f --- /dev/null +++ b/sample/phxkv/Makefile.define @@ -0,0 +1,51 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=elibphxkv_client.a phxkv_client_tools phxkv_grpcserver + +PHXKV_CLIENT_OBJ=phxkv.pb.o phxkv.grpc.pb.o kv_grpc_client.o kv_grpc_client_main.o utils.o + +PHXKV_CLIENT_LIB=phxkv_client + +PHXKV_CLIENT_SYS_LIB=$(GRPC_LIBE_PATH)/libgrpc++_unsecure.a $(GRPC_LIBE_PATH)/libgrpc.a -lssl -lcrypto -ldl -lz -lrt $(PROTOBUF_LIB_PATH)/libprotobuf.a $(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread + +PHXKV_CLIENT_INCS=$(SRC_BASE_PATH)/sample/phxkv $(GRPC_INCLUDE_PATH) $(PHXPAXOS_INCLUDE_PATH) $(LEVELDB_INCLUDE_PATH) $(PROTOBUF_INCLUDE_PATH) + +PHXKV_CLIENT_EXTRA_CPPFLAGS=-Wall + +PHXKV_CLIENT_TOOLS_OBJ=phxkv.pb.o phxkv.grpc.pb.o kv_grpc_client.o kv_grpc_client_main.o + +PHXKV_CLIENT_TOOLS_LIB=sample/phxkv:phxkv_client + +PHXKV_CLIENT_TOOLS_SYS_LIB= + +PHXKV_CLIENT_TOOLS_INCS=$(SRC_BASE_PATH)/sample/phxkv + +PHXKV_CLIENT_TOOLS_EXTRA_CPPFLAGS=-Wall + +PHXKV_GRPCSERVER_OBJ=phxkv.pb.o phxkv.grpc.pb.o kv.o kvsm.o kv_paxos.o log.o kv_grpc_server.o kv_grpc_server_main.o utils.o + +PHXKV_GRPCSERVER_LIB= + +PHXKV_GRPCSERVER_SYS_LIB=$(PHXPAXOS_LIB_PATH)/libphxpaxos_plugin.a $(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread $(GLOG_LIB_PATH)/libglog.a $(GRPC_LIBE_PATH)/libgrpc++_unsecure.a $(GRPC_LIBE_PATH)/libgrpc.a -lssl -lcrypto -ldl -lz -lrt $(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread $(GLOG_LIB_PATH)/libglog.a -lpthread + +PHXKV_GRPCSERVER_INCS=$(SRC_BASE_PATH)/sample/phxkv $(PHXPAXOS_PLUGIN_PATH) $(GRPC_INCLUDE_PATH) $(GRPC_INCLUDE_PATH) $(PHXPAXOS_INCLUDE_PATH) $(LEVELDB_INCLUDE_PATH) $(PROTOBUF_INCLUDE_PATH) + +PHXKV_GRPCSERVER_EXTRA_CPPFLAGS=-Wall + diff --git a/sample/phxkv/README b/sample/phxkv/README new file mode 100644 index 000000000..d45546aad --- /dev/null +++ b/sample/phxkv/README @@ -0,0 +1,9 @@ +This is a sample that make leveldb base on paxos to build a strong consistent distributed kv. +Also, this sample show you how to unite grpc(maybe other rcp) and phxpaxos. + +#run server +First check prepare_dir.sh to prepare all dir for server. +Then check run_server_sample.sh to get command to run server. + +#use client tools +Check client_tools_sample.sh. diff --git a/sample/phxkv/client_tools_sample.sh b/sample/phxkv/client_tools_sample.sh new file mode 100644 index 000000000..7b97c80b7 --- /dev/null +++ b/sample/phxkv/client_tools_sample.sh @@ -0,0 +1,14 @@ +#./phxkv_client_tools 127.0.0.1:21112 put key_hello value_paxos 0 +#./phxkv_client_tools 127.0.0.1:21112 getlocal key_hello +#./phxkv_client_tools 127.0.0.1:21112 getglobal key_hello +#./phxkv_client_tools 127.0.0.1:21112 delete key_hello 0 + +#./phxkv_client_tools 127.0.0.1:21111 put key_hello value_paxos 0 +#./phxkv_client_tools 127.0.0.1:21111 getlocal key_hello +#./phxkv_client_tools 127.0.0.1:21111 getglobal key_hello +#./phxkv_client_tools 127.0.0.1:21111 delete key_hello 0 + +#./phxkv_client_tools 127.0.0.1:21113 put key_hello value_paxos 0 +#./phxkv_client_tools 127.0.0.1:21113 getlocal key_hello +#./phxkv_client_tools 127.0.0.1:21113 getglobal key_hello +#./phxkv_client_tools 127.0.0.1:21113 delete key_hello 0 diff --git a/sample/phxkv/def.h b/sample/phxkv/def.h new file mode 100644 index 000000000..133411fbd --- /dev/null +++ b/sample/phxkv/def.h @@ -0,0 +1,49 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +namespace phxkv +{ + +const uint64_t NullVersion = std::numeric_limits::min(); + +enum class PhxKVStatus +{ + SUCC = 0, + FAIL = -1, + KEY_NOTEXIST = 1, + VERSION_CONFLICT = -11, + VERSION_NOTEXIST = -12, + MASTER_REDIRECT = 10, + NO_MASTER = 101, +}; + + +enum KVOperatorType +{ + KVOperatorType_READ = 1, + KVOperatorType_WRITE = 2, + KVOperatorType_DELETE = 3, +}; + + +} diff --git a/sample/phxkv/kv.cpp b/sample/phxkv/kv.cpp new file mode 100644 index 000000000..bc0977718 --- /dev/null +++ b/sample/phxkv/kv.cpp @@ -0,0 +1,279 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "kv.h" +#include "phxkv.pb.h" +#include "log.h" + +using namespace phxpaxos; +using namespace std; + +namespace phxkv +{ + +KVClient :: KVClient() +{ + m_bHasInit = false; + m_poLevelDB = nullptr; +} + +KVClient :: ~KVClient() +{ +} + +bool KVClient :: Init(const std::string & sDBPath) +{ + if (m_bHasInit) + { + return true; + } + + leveldb::Options oOptions; + oOptions.create_if_missing = true; + leveldb::Status oStatus = leveldb::DB::Open(oOptions, sDBPath, &m_poLevelDB); + + if (!oStatus.ok()) + { + PLErr("Open leveldb fail, db_path %s", sDBPath.c_str()); + return false; + } + + m_bHasInit = true; + + PLImp("OK, db_path %s", sDBPath.c_str()); + + return true; +} + +KVClient * KVClient :: Instance() +{ + static KVClient oKVClient; + return &oKVClient; +} + +KVClientRet KVClient :: Get(const std::string & sKey, std::string & sValue, uint64_t & llVersion) +{ + if (!m_bHasInit) + { + PLErr("no init yet"); + return KVCLIENT_SYS_FAIL; + } + + string sBuffer; + leveldb::Status oStatus = m_poLevelDB->Get(leveldb::ReadOptions(), sKey, &sBuffer); + if (!oStatus.ok()) + { + if (oStatus.IsNotFound()) + { + PLErr("LevelDB.Get not found, key %s", sKey.c_str()); + llVersion = 0; + return KVCLIENT_KEY_NOTEXIST; + } + + PLErr("LevelDB.Get fail, key %s", sKey.c_str()); + return KVCLIENT_SYS_FAIL; + } + + KVData oData; + bool bSucc = oData.ParseFromArray(sBuffer.data(), sBuffer.size()); + if (!bSucc) + { + PLErr("DB DATA wrong, key %s", sKey.c_str()); + return KVCLIENT_SYS_FAIL; + } + + llVersion = oData.version(); + + if (oData.isdeleted()) + { + PLErr("LevelDB.Get key already deleted, key %s", sKey.c_str()); + return KVCLIENT_KEY_NOTEXIST; + } + + sValue = oData.value(); + + PLImp("OK, key %s value %s version %lu", sKey.c_str(), sValue.c_str(), llVersion); + + return KVCLIENT_OK; +} + +KVClientRet KVClient :: Set(const std::string & sKey, const std::string & sValue, const uint64_t llVersion) +{ + if (!m_bHasInit) + { + PLErr("no init yet"); + return KVCLIENT_SYS_FAIL; + } + + ScopedLock oLockGuard(m_oMutex); + + uint64_t llServerVersion = 0; + std::string sServerValue; + KVClientRet ret = Get(sKey, sServerValue, llServerVersion); + if (ret != KVCLIENT_OK && ret != KVCLIENT_KEY_NOTEXIST) + { + return KVCLIENT_SYS_FAIL; + } + + if (llServerVersion != llVersion) + { + return KVCLIENT_KEY_VERSION_CONFLICT; + } + + llServerVersion++; + KVData oData; + oData.set_value(sValue); + oData.set_version(llServerVersion); + oData.set_isdeleted(false); + + std::string sBuffer; + bool bSucc = oData.SerializeToString(&sBuffer); + if (!bSucc) + { + PLErr("Data.SerializeToString fail"); + return KVCLIENT_SYS_FAIL; + } + + leveldb::Status oStatus = m_poLevelDB->Put(leveldb::WriteOptions(), sKey, sBuffer); + if (!oStatus.ok()) + { + PLErr("LevelDB.Put fail, key %s bufferlen %zu", sKey.c_str(), sBuffer.size()); + return KVCLIENT_SYS_FAIL; + } + + PLImp("OK, key %s value %s version %lu", sKey.c_str(), sValue.c_str(), llVersion); + + return KVCLIENT_OK; +} + +KVClientRet KVClient :: Del(const std::string & sKey, const uint64_t llVersion) +{ + if (!m_bHasInit) + { + PLErr("no init yet"); + return KVCLIENT_SYS_FAIL; + } + + ScopedLock oLockGuard(m_oMutex); + + uint64_t llServerVersion = 0; + std::string sServerValue; + KVClientRet ret = Get(sKey, sServerValue, llServerVersion); + if (ret != KVCLIENT_OK && ret != KVCLIENT_KEY_NOTEXIST) + { + return KVCLIENT_SYS_FAIL; + } + + if (llServerVersion != llVersion) + { + return KVCLIENT_KEY_VERSION_CONFLICT; + } + + llServerVersion++; + KVData oData; + oData.set_value(sServerValue); + oData.set_version(llServerVersion); + oData.set_isdeleted(true); + + std::string sBuffer; + bool bSucc = oData.SerializeToString(&sBuffer); + if (!bSucc) + { + PLErr("Data.SerializeToString fail"); + return KVCLIENT_SYS_FAIL; + } + + leveldb::Status oStatus = m_poLevelDB->Put(leveldb::WriteOptions(), sKey, sBuffer); + if (!oStatus.ok()) + { + PLErr("LevelDB.Put fail, key %s bufferlen %zu", sKey.c_str(), sBuffer.size()); + return KVCLIENT_SYS_FAIL; + } + + PLImp("OK, key %s version %lu", sKey.c_str(), llVersion); + + return KVCLIENT_OK; +} + +KVClientRet KVClient :: GetCheckpointInstanceID(uint64_t & llCheckpointInstanceID) +{ + if (!m_bHasInit) + { + PLErr("no init yet"); + return KVCLIENT_SYS_FAIL; + } + + string sKey; + static uint64_t llCheckpointInstanceIDKey = KV_CHECKPOINT_KEY; + sKey.append((char *)&llCheckpointInstanceIDKey, sizeof(uint64_t)); + + string sBuffer; + leveldb::Status oStatus = m_poLevelDB->Get(leveldb::ReadOptions(), sKey, &sBuffer); + if (!oStatus.ok()) + { + if (oStatus.IsNotFound()) + { + return KVCLIENT_KEY_NOTEXIST; + } + + return KVCLIENT_SYS_FAIL; + } + + memcpy(&llCheckpointInstanceID, sBuffer.data(), sizeof(uint64_t)); + + PLImp("OK, CheckpointInstanceID %lu", llCheckpointInstanceID); + + return KVCLIENT_OK; +} + +KVClientRet KVClient :: SetCheckpointInstanceID(const uint64_t llCheckpointInstanceID) +{ + if (!m_bHasInit) + { + PLErr("no init yet"); + return KVCLIENT_SYS_FAIL; + } + + string sKey; + static uint64_t llCheckpointInstanceIDKey = KV_CHECKPOINT_KEY; + sKey.append((char *)&llCheckpointInstanceIDKey, sizeof(uint64_t)); + + string sBuffer; + sBuffer.append((char *)&llCheckpointInstanceID, sizeof(uint64_t)); + + leveldb::WriteOptions oWriteOptions; + //must fync + oWriteOptions.sync = true; + + leveldb::Status oStatus = m_poLevelDB->Put(oWriteOptions, sKey, sBuffer); + if (!oStatus.ok()) + { + PLErr("LevelDB.Put fail, bufferlen %zu", sBuffer.size()); + return KVCLIENT_SYS_FAIL; + } + + PLImp("OK, CheckpointInstanceID %lu", llCheckpointInstanceID); + + return KVCLIENT_OK; +} + +} + diff --git a/sample/phxkv/kv.h b/sample/phxkv/kv.h new file mode 100644 index 000000000..c3b9f5dd5 --- /dev/null +++ b/sample/phxkv/kv.h @@ -0,0 +1,67 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "leveldb/db.h" +#include +#include "utils.h" + +namespace phxkv +{ + +enum KVClientRet +{ + KVCLIENT_OK = 0, + KVCLIENT_SYS_FAIL = -1, + KVCLIENT_KEY_NOTEXIST = 1, + KVCLIENT_KEY_VERSION_CONFLICT = -11, +}; + +#define KV_CHECKPOINT_KEY ((uint64_t)-1) + +class KVClient +{ +public: + KVClient(); + ~KVClient(); + + bool Init(const std::string & sDBPath); + + static KVClient * Instance(); + + KVClientRet Get(const std::string & sKey, std::string & sValue, uint64_t & llVersion); + + KVClientRet Set(const std::string & sKey, const std::string & sValue, const uint64_t llVersion); + + KVClientRet Del(const std::string & sKey, const uint64_t llVersion); + + KVClientRet GetCheckpointInstanceID(uint64_t & llCheckpointInstanceID); + + KVClientRet SetCheckpointInstanceID(const uint64_t llCheckpointInstanceID); + +private: + leveldb::DB * m_poLevelDB; + bool m_bHasInit; + Mutex m_oMutex; +}; + +} diff --git a/sample/phxkv/kv_grpc_client.cpp b/sample/phxkv/kv_grpc_client.cpp new file mode 100644 index 000000000..227a5d1d1 --- /dev/null +++ b/sample/phxkv/kv_grpc_client.cpp @@ -0,0 +1,231 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "kv_grpc_client.h" +#include "phxpaxos/options.h" + +using grpc::Channel; +using grpc::ClientContext; +using grpc::Status; +using namespace phxpaxos; +using namespace std; + +namespace phxkv +{ + +PhxKVClient :: PhxKVClient(std::shared_ptr channel) + : stub_(PhxKVServer::NewStub(channel)) +{ +} + +void PhxKVClient :: NewChannel(const uint64_t llNodeID) +{ + NodeInfo oNodeInfo(llNodeID); + + //for test multi node in one machine, each node have difference grpc_port. + //but normally, every node's grpc_port is same, so you just set your grpc_port. + //if you change paxos_port/grpc_port's relation, you must modify this line. + int iGrpcPort = oNodeInfo.GetPort() + 10000; + + char sAddress[128] = {0}; + snprintf(sAddress, sizeof(sAddress), "%s:%d", oNodeInfo.GetIP().c_str(), iGrpcPort); + + string sServerAddress = sAddress; + + printf("%s %s\n", __func__, sAddress); + + stub_.reset(nullptr); + + stub_ = PhxKVServer::NewStub(grpc::CreateChannel(sServerAddress, + grpc::InsecureChannelCredentials())); +} + +int PhxKVClient :: Put( + const std::string & sKey, + const std::string & sValue, + const uint64_t llVersion, + const int iDeep) +{ + if (iDeep > 3) + { + return static_cast(PhxKVStatus::FAIL); + } + + KVOperator oRequest; + oRequest.set_key(sKey); + oRequest.set_value(sValue); + oRequest.set_version(llVersion); + oRequest.set_operator_(KVOperatorType_WRITE); + + KVResponse oResponse; + ClientContext context; + Status status = stub_->Put(&context, oRequest, &oResponse); + + if (status.ok()) + { + if (oResponse.ret() == static_cast(PhxKVStatus::MASTER_REDIRECT)) + { + if (oResponse.master_nodeid() != phxpaxos::nullnode) + { + NewChannel(oResponse.master_nodeid()); + return Put(sKey, sValue, llVersion, iDeep + 1); + } + else + { + return static_cast(PhxKVStatus::NO_MASTER); + } + } + + return oResponse.ret(); + } + else + { + return static_cast(PhxKVStatus::FAIL); + } +} + +int PhxKVClient :: GetLocal( + const std::string & sKey, + std::string & sValue, + uint64_t & llVersion) +{ + KVOperator oRequest; + oRequest.set_key(sKey); + oRequest.set_operator_(KVOperatorType_READ); + + KVResponse oResponse; + ClientContext context; + Status status = stub_->GetLocal(&context, oRequest, &oResponse); + + if (status.ok()) + { + sValue = oResponse.data().value(); + llVersion = oResponse.data().version(); + return oResponse.ret(); + } + else + { + return static_cast(PhxKVStatus::FAIL); + } +} + +int PhxKVClient :: GetLocal( + const std::string & sKey, + const uint64_t minVersion, + std::string & sValue, + uint64_t & llVersion) +{ + int ret = GetLocal(sKey, sValue, llVersion); + if (ret == 0) + { + if (llVersion < minVersion) + { + return static_cast(PhxKVStatus::VERSION_NOTEXIST); + } + } + + return ret; +} + +int PhxKVClient :: Delete( + const std::string & sKey, + const uint64_t llVersion, + const int iDeep) +{ + KVOperator oRequest; + oRequest.set_key(sKey); + oRequest.set_version(llVersion); + oRequest.set_operator_(KVOperatorType_DELETE); + + KVResponse oResponse; + ClientContext context; + Status status = stub_->Delete(&context, oRequest, &oResponse); + + if (status.ok()) + { + if (oResponse.ret() == static_cast(PhxKVStatus::MASTER_REDIRECT)) + { + if (oResponse.master_nodeid() != phxpaxos::nullnode) + { + NewChannel(oResponse.master_nodeid()); + return Delete(sKey, llVersion, iDeep + 1); + } + else + { + return static_cast(PhxKVStatus::NO_MASTER); + } + } + + return oResponse.ret(); + } + else + { + return static_cast(PhxKVStatus::FAIL); + } +} + +int PhxKVClient :: GetGlobal( + const std::string & sKey, + std::string & sValue, + uint64_t & llVersion, + const int iDeep) +{ + if (iDeep > 3) + { + return static_cast(PhxKVStatus::FAIL); + } + + KVOperator oRequest; + oRequest.set_key(sKey); + oRequest.set_operator_(KVOperatorType_READ); + + KVResponse oResponse; + ClientContext context; + Status status = stub_->GetGlobal(&context, oRequest, &oResponse); + + if (status.ok()) + { + if (oResponse.ret() == static_cast(PhxKVStatus::MASTER_REDIRECT)) + { + if (oResponse.master_nodeid() != phxpaxos::nullnode) + { + NewChannel(oResponse.master_nodeid()); + return GetGlobal(sKey, sValue, llVersion, iDeep + 1); + } + else + { + return static_cast(PhxKVStatus::NO_MASTER); + } + } + + sValue = oResponse.data().value(); + llVersion = oResponse.data().version(); + + return oResponse.ret(); + } + else + { + return static_cast(PhxKVStatus::FAIL); + } +} + +} + diff --git a/sample/phxkv/kv_grpc_client.h b/sample/phxkv/kv_grpc_client.h new file mode 100644 index 000000000..fd29b27a5 --- /dev/null +++ b/sample/phxkv/kv_grpc_client.h @@ -0,0 +1,76 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include + +#include + +#include "phxkv.grpc.pb.h" + +#include "def.h" + +namespace phxkv +{ + +class PhxKVClient +{ +public: + PhxKVClient(std::shared_ptr channel); + + void NewChannel(const uint64_t llNodeID); + + int Put( + const std::string & sKey, + const std::string & sValue, + const uint64_t llVersion, + const int iDeep = 0); + + int GetLocal( + const std::string & sKey, + std::string & sValue, + uint64_t & llVersion); + + int GetLocal( + const std::string & sKey, + const uint64_t minVersion, + std::string & sValue, + uint64_t & llVersion); + + int Delete( + const std::string & sKey, + const uint64_t llVersion, + const int iDeep = 0); + + int GetGlobal( + const std::string & sKey, + std::string & sValue, + uint64_t & llVersion, + const int iDeep = 0); + +private: + std::unique_ptr stub_; +}; + +} diff --git a/sample/phxkv/kv_grpc_client_main.cpp b/sample/phxkv/kv_grpc_client_main.cpp new file mode 100644 index 000000000..d5b9de270 --- /dev/null +++ b/sample/phxkv/kv_grpc_client_main.cpp @@ -0,0 +1,172 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "kv_grpc_client.h" + +using namespace std; +using namespace phxkv; + +void Put(PhxKVClient & oPhxKVClient, const string & sKey, const string & sValue, const uint64_t llVersion) +{ + int ret = oPhxKVClient.Put(sKey, sValue, llVersion); + if (ret == 0) + { + printf("Put ok, key %s value %s version %lu\n", + sKey.c_str(), sValue.c_str(), llVersion); + } + else if (ret == -11) + { + printf("Put version conflict, key %s value %s version %lu\n", + sKey.c_str(), sValue.c_str(), llVersion); + } + else + { + printf("Put fail, ret %d, key %s value %s version %lu\n", + ret, sKey.c_str(), sValue.c_str(), llVersion); + } +} + +void GetGlobal(PhxKVClient & oPhxKVClient, const string & sKey) +{ + string sReadValue; + uint64_t iReadVersion = 0; + int ret = oPhxKVClient.GetGlobal(sKey, sReadValue, iReadVersion); + if (ret == 0) + { + printf("GetGlobal ok, key %s value %s version %lu\n", + sKey.c_str(), sReadValue.c_str(), iReadVersion); + } + else if (ret == 1) + { + printf("GetGlobal key %s not exist\n", sKey.c_str()); + } + else if (ret == 101) + { + printf("GetGlobal no master\n"); + } + else + { + printf("GetGlobal fail, ret %d key %s\n", ret, sKey.c_str()); + } +} + +void GetLocal(PhxKVClient & oPhxKVClient, const string & sKey) +{ + string sReadValue; + uint64_t iReadVersion = 0; + int ret = oPhxKVClient.GetLocal(sKey, sReadValue, iReadVersion); + if (ret == 0) + { + printf("GetLocal ok, key %s value %s version %lu\n", + sKey.c_str(), sReadValue.c_str(), iReadVersion); + } + else if (ret == 1) + { + printf("GetLocal key %s not exist\n", sKey.c_str()); + } + else + { + printf("GetLocal fail, ret %d key %s\n", ret, sKey.c_str()); + } +} + +void Delete(PhxKVClient & oPhxKVClient, const string & sKey, const uint64_t llVersion) +{ + int ret = oPhxKVClient.Delete(sKey, llVersion); + if (ret == 0) + { + printf("Delete ok, key %s version %lu\n", + sKey.c_str(), llVersion); + } + else if (ret == -11) + { + printf("Delete version conflict, key %s version %lu\n", + sKey.c_str(), llVersion); + } + else + { + printf("Delete fail, ret %d key %s\n", ret, sKey.c_str()); + } +} + +void usage(char ** argv) +{ + printf("%s \n", argv[0]); + printf("%s \n", argv[0]); + printf("%s \n", argv[0]); + printf("%s \n", argv[0]); +} + +int main(int argc, char ** argv) +{ + if (argc < 4) + { + usage(argv); + return -2; + } + + string sServerAddress = argv[1]; + + PhxKVClient oPhxKVClient(grpc::CreateChannel( + sServerAddress, grpc::InsecureChannelCredentials())); + + string sFunc = argv[2]; + string sKey = argv[3]; + + if (sFunc == "put") + { + if (argc < 6) + { + usage(argv); + return -2; + } + + string sValue = argv[4]; + uint64_t llVersion = strtoull(argv[5], NULL, 10); + Put(oPhxKVClient, sKey, sValue, llVersion); + } + else if (sFunc == "getlocal") + { + GetLocal(oPhxKVClient, sKey); + } + else if (sFunc == "getglobal") + { + GetGlobal(oPhxKVClient, sKey); + } + else if (sFunc == "delete") + { + if (argc < 5) + { + usage(argv); + return -2; + } + + uint64_t llVersion = strtoull(argv[4], NULL, 10); + Delete(oPhxKVClient, sKey, llVersion); + } + else + { + usage(argv); + } + + return 0; +} + diff --git a/sample/phxkv/kv_grpc_server.cpp b/sample/phxkv/kv_grpc_server.cpp new file mode 100644 index 000000000..31d870cbc --- /dev/null +++ b/sample/phxkv/kv_grpc_server.cpp @@ -0,0 +1,127 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "kv_grpc_server.h" + +using grpc::ServerContext; +using grpc::Status; +using namespace std; + +namespace phxkv +{ + + +PhxKVServiceImpl :: PhxKVServiceImpl(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList, + const std::string & sKVDBPath, const std::string & sPaxosLogPath) + : m_oPhxKV(oMyNode, vecNodeList, sKVDBPath, sPaxosLogPath) +{ +} + +int PhxKVServiceImpl :: Init() +{ + return m_oPhxKV.RunPaxos(); +} + +Status PhxKVServiceImpl :: Put(ServerContext* context, const KVOperator * request, KVResponse * reply) +{ + if (!m_oPhxKV.IsIMMaster(request->key())) + { + reply->set_ret((int)PhxKVStatus::MASTER_REDIRECT); + uint64_t llMasterNodeID = m_oPhxKV.GetMaster(request->key()).GetNodeID(); + reply->set_master_nodeid(llMasterNodeID); + + PLImp("I'm not master, need redirect, master nodeid i saw %lu, key %s version %lu", + llMasterNodeID, request->key().c_str(), request->version()); + return Status::OK; + } + + PhxKVStatus status = m_oPhxKV.Put(request->key(), request->value(), request->version()); + reply->set_ret((int)status); + + PLImp("ret %d, key %s version %lu", reply->ret(), request->key().c_str(), request->version()); + + return Status::OK; +} + +Status PhxKVServiceImpl :: GetLocal(ServerContext* context, const KVOperator * request, KVResponse * reply) +{ + string sReadValue; + uint64_t llReadVersion = 0; + + PhxKVStatus status = m_oPhxKV.GetLocal(request->key(), sReadValue, llReadVersion); + if (status == PhxKVStatus::SUCC) + { + reply->mutable_data()->set_value(sReadValue); + reply->mutable_data()->set_version(llReadVersion); + } + else if (status == PhxKVStatus::KEY_NOTEXIST) + { + reply->mutable_data()->set_isdeleted(true); + } + + reply->set_ret((int)status); + + PLImp("ret %d, key %s version %lu", reply->ret(), request->key().c_str(), llReadVersion); + + return Status::OK; +} + +Status PhxKVServiceImpl :: GetGlobal(ServerContext* context, const KVOperator * request, KVResponse * reply) +{ + if (!m_oPhxKV.IsIMMaster(request->key())) + { + reply->set_ret((int)PhxKVStatus::MASTER_REDIRECT); + uint64_t llMasterNodeID = m_oPhxKV.GetMaster(request->key()).GetNodeID(); + reply->set_master_nodeid(llMasterNodeID); + + PLImp("I'm not master, need redirect, master nodeid i saw %lu, key %s version %lu", + llMasterNodeID, request->key().c_str(), request->version()); + + return Status::OK; + } + + return GetLocal(context, request, reply); +} + +Status PhxKVServiceImpl :: Delete(ServerContext* context, const KVOperator * request, KVResponse * reply) +{ + if (!m_oPhxKV.IsIMMaster(request->key())) + { + reply->set_ret((int)PhxKVStatus::MASTER_REDIRECT); + uint64_t llMasterNodeID = m_oPhxKV.GetMaster(request->key()).GetNodeID(); + reply->set_master_nodeid(llMasterNodeID); + + PLImp("I'm not master, need redirect, master nodeid i saw %lu, key %s version %lu", + llMasterNodeID, request->key().c_str(), request->version()); + + return Status::OK; + } + + PhxKVStatus status = m_oPhxKV.Delete(request->key(), request->version()); + reply->set_ret((int)status); + + PLImp("ret %d, key %s version %lu", reply->ret(), request->key().c_str(), request->version()); + + return Status::OK; +} + +} + diff --git a/sample/phxkv/kv_grpc_server.h b/sample/phxkv/kv_grpc_server.h new file mode 100644 index 000000000..be442b355 --- /dev/null +++ b/sample/phxkv/kv_grpc_server.h @@ -0,0 +1,51 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include "phxkv.grpc.pb.h" +#include "kv_paxos.h" + +namespace phxkv +{ + +class PhxKVServiceImpl final : public PhxKVServer::Service +{ +public: + PhxKVServiceImpl(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList, + const std::string & sKVDBPath, const std::string & sPaxosLogPath); + + int Init(); + + grpc::Status Put(grpc::ServerContext* context, const KVOperator * request, KVResponse * reply) override; + + grpc::Status GetLocal(grpc::ServerContext* context, const KVOperator * request, KVResponse * reply) override; + + grpc::Status GetGlobal(grpc::ServerContext* context, const KVOperator * request, KVResponse * reply) override; + + grpc::Status Delete(grpc::ServerContext* context, const KVOperator * request, KVResponse * reply) override; + +private: + PhxKV m_oPhxKV; +}; + +} diff --git a/sample/phxkv/kv_grpc_server_main.cpp b/sample/phxkv/kv_grpc_server_main.cpp new file mode 100644 index 000000000..06531c7bb --- /dev/null +++ b/sample/phxkv/kv_grpc_server_main.cpp @@ -0,0 +1,148 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "kv_grpc_server.h" +#include +#include +#include +#include "log.h" + +#include + +using namespace phxpaxos; +using namespace phxkv; +using namespace std; +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; + +int parse_ipport(const char * pcStr, NodeInfo & oNodeInfo) +{ + char sIP[32] = {0}; + int iPort = -1; + + int count = sscanf(pcStr, "%[^':']:%d", sIP, &iPort); + if (count != 2) + { + return -1; + } + + oNodeInfo.SetIPPort(sIP, iPort); + + return 0; +} + +int parse_ipport_list(const char * pcStr, NodeInfoList & vecNodeInfoList) +{ + string sTmpStr; + int iStrLen = strlen(pcStr); + + for (int i = 0; i < iStrLen; i++) + { + if (pcStr[i] == ',' || i == iStrLen - 1) + { + if (i == iStrLen - 1 && pcStr[i] != ',') + { + sTmpStr += pcStr[i]; + } + + NodeInfo oNodeInfo; + int ret = parse_ipport(sTmpStr.c_str(), oNodeInfo); + if (ret != 0) + { + return ret; + } + + vecNodeInfoList.push_back(oNodeInfo); + + sTmpStr = ""; + } + else + { + sTmpStr += pcStr[i]; + } + } + + return 0; +} + +int main(int argc, char ** argv) +{ + if (argc < 6) + { + printf("%s \n", argv[0]); + return -1; + } + + string sServerAddress = argv[1]; + + NodeInfo oMyNode; + if (parse_ipport(argv[2], oMyNode) != 0) + { + printf("parse myip:myport fail\n"); + return -1; + } + + NodeInfoList vecNodeInfoList; + if (parse_ipport_list(argv[3], vecNodeInfoList) != 0) + { + printf("parse ip/port list fail\n"); + return -1; + } + + string sKVDBPath = argv[4]; + string sPaxosLogPath = argv[5]; + + int ret = LOGGER->Init("phxkv", "./log", 3); + if (ret != 0) + { + printf("server log init fail, ret %d\n", ret); + return ret; + } + + NLDebug("server init start............................."); + + PhxKVServiceImpl oPhxKVServer(oMyNode, vecNodeInfoList, sKVDBPath, sPaxosLogPath); + ret = oPhxKVServer.Init(); + if (ret != 0) + { + printf("server init fail, ret %d\n", ret); + return ret; + } + + NLDebug("server init ok............................."); + + ServerBuilder oBuilder; + + oBuilder.AddListeningPort(sServerAddress, grpc::InsecureServerCredentials()); + + oBuilder.RegisterService(&oPhxKVServer); + + std::unique_ptr server(oBuilder.BuildAndStart()); + std::cout << "Server listening on " << sServerAddress << std::endl; + + server->Wait(); + + return 0; +} + + diff --git a/sample/phxkv/kv_paxos.cpp b/sample/phxkv/kv_paxos.cpp new file mode 100644 index 000000000..0f776e246 --- /dev/null +++ b/sample/phxkv/kv_paxos.cpp @@ -0,0 +1,226 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "kv_paxos.h" +#include +#include +#include +#include +#include +#include + +using namespace phxpaxos; +using namespace std; + +namespace phxkv +{ + +PhxKV :: PhxKV(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList, + const std::string & sKVDBPath, const std::string & sPaxosLogPath) + : m_oMyNode(oMyNode), m_vecNodeList(vecNodeList), + m_sKVDBPath(sKVDBPath), m_sPaxosLogPath(sPaxosLogPath), + m_poPaxosNode(nullptr), m_oPhxKVSM(sKVDBPath) +{ + //only show you how to use multi paxos group, you can set as 1, 2, or any other number. + //not too large. + m_iGroupCount = 3; +} + +PhxKV :: ~PhxKV() +{ + delete m_poPaxosNode; +} + +const phxpaxos::NodeInfo PhxKV :: GetMaster(const std::string & sKey) +{ + int iGroupIdx = GetGroupIdx(sKey); + return m_poPaxosNode->GetMaster(iGroupIdx); +} + +const bool PhxKV :: IsIMMaster(const std::string & sKey) +{ + int iGroupIdx = GetGroupIdx(sKey); + return m_poPaxosNode->IsIMMaster(iGroupIdx); +} + +int PhxKV :: RunPaxos() +{ + bool bSucc = m_oPhxKVSM.Init(); + if (!bSucc) + { + return -1; + } + + Options oOptions; + + oOptions.sLogStoragePath = m_sPaxosLogPath; + + //this groupcount means run paxos group count. + //every paxos group is independent, there are no any communicate between any 2 paxos group. + oOptions.iGroupCount = m_iGroupCount; + + oOptions.oMyNode = m_oMyNode; + oOptions.vecNodeInfoList = m_vecNodeList; + + //because all group share state machine(kv), so every group have same sate machine. + //just for split key to different paxos group, to upgrate performance. + for (int iGroupIdx = 0; iGroupIdx < m_iGroupCount; iGroupIdx++) + { + GroupSMInfo oSMInfo; + oSMInfo.iGroupIdx = iGroupIdx; + oSMInfo.vecSMList.push_back(&m_oPhxKVSM); + oSMInfo.bIsUseMaster = true; + + oOptions.vecGroupSMInfoList.push_back(oSMInfo); + } + + //set logfunc + oOptions.pLogFunc = LOGGER->GetLogFunc(); + + int ret = Node::RunNode(oOptions, m_poPaxosNode); + if (ret != 0) + { + PLErr("run paxos fail, ret %d", ret); + return ret; + } + + PLImp("run paxos ok\n"); + return 0; +} + +int PhxKV :: GetGroupIdx(const std::string & sKey) +{ + uint32_t iHashNum = 0; + for (size_t i = 0; i < sKey.size(); i++) + { + iHashNum = iHashNum * 7 + ((int)sKey[i]); + } + + return iHashNum % m_iGroupCount; +} + +int PhxKV :: KVPropose(const std::string & sKey, const std::string & sPaxosValue, PhxKVSMCtx & oPhxKVSMCtx) +{ + int iGroupIdx = GetGroupIdx(sKey); + + SMCtx oCtx; + //smid must same to PhxKVSM.SMID(). + oCtx.m_iSMID = 1; + oCtx.m_pCtx = (void *)&oPhxKVSMCtx; + + uint64_t llInstanceID = 0; + int ret = m_poPaxosNode->Propose(iGroupIdx, sPaxosValue, llInstanceID, &oCtx); + if (ret != 0) + { + PLErr("paxos propose fail, key %s groupidx %d ret %d", iGroupIdx, ret); + return ret; + } + + return 0; +} + +PhxKVStatus PhxKV :: Put( + const std::string & sKey, + const std::string & sValue, + const uint64_t llVersion) +{ + string sPaxosValue; + bool bSucc = PhxKVSM::MakeSetOpValue(sKey, sValue, llVersion, sPaxosValue); + if (!bSucc) + { + return PhxKVStatus::FAIL; + } + + PhxKVSMCtx oPhxKVSMCtx; + int ret = KVPropose(sKey, sPaxosValue, oPhxKVSMCtx); + if (ret != 0) + { + return PhxKVStatus::FAIL; + } + + if (oPhxKVSMCtx.iExecuteRet == KVCLIENT_OK) + { + return PhxKVStatus::SUCC; + } + else if (oPhxKVSMCtx.iExecuteRet == KVCLIENT_KEY_VERSION_CONFLICT) + { + return PhxKVStatus::VERSION_CONFLICT; + } + else + { + return PhxKVStatus::FAIL; + } +} + +PhxKVStatus PhxKV :: GetLocal( + const std::string & sKey, + std::string & sValue, + uint64_t & llVersion) +{ + int ret = m_oPhxKVSM.GetKVClient()->Get(sKey, sValue, llVersion); + if (ret == KVCLIENT_OK) + { + return PhxKVStatus::SUCC; + } + else if (ret == KVCLIENT_KEY_NOTEXIST) + { + return PhxKVStatus::KEY_NOTEXIST; + } + else + { + return PhxKVStatus::FAIL; + } +} + +PhxKVStatus PhxKV :: Delete( + const std::string & sKey, + const uint64_t llVersion) +{ + string sPaxosValue; + bool bSucc = PhxKVSM::MakeDelOpValue(sKey, llVersion, sPaxosValue); + if (!bSucc) + { + return PhxKVStatus::FAIL; + } + + PhxKVSMCtx oPhxKVSMCtx; + int ret = KVPropose(sKey, sPaxosValue, oPhxKVSMCtx); + if (ret != 0) + { + return PhxKVStatus::FAIL; + } + + if (oPhxKVSMCtx.iExecuteRet == KVCLIENT_OK) + { + return PhxKVStatus::SUCC; + } + else if (oPhxKVSMCtx.iExecuteRet == KVCLIENT_KEY_VERSION_CONFLICT) + { + return PhxKVStatus::VERSION_CONFLICT; + } + else + { + return PhxKVStatus::FAIL; + } +} + +} + diff --git a/sample/phxkv/kv_paxos.h b/sample/phxkv/kv_paxos.h new file mode 100644 index 000000000..c988e3955 --- /dev/null +++ b/sample/phxkv/kv_paxos.h @@ -0,0 +1,81 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/node.h" +#include "kvsm.h" +#include +#include +#include "phxpaxos_plugin/logger_google.h" +#include "log.h" +#include "def.h" + +namespace phxkv +{ + + +class PhxKV +{ +public: + PhxKV(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList, + const std::string & sKVDBPath, const std::string & sPaxosLogPath); + ~PhxKV(); + + int RunPaxos(); + + const phxpaxos::NodeInfo GetMaster(const std::string & sKey); + + const bool IsIMMaster(const std::string & sKey); + + PhxKVStatus Put( + const std::string & sKey, + const std::string & sValue, + const uint64_t llVersion = NullVersion); + + PhxKVStatus GetLocal( + const std::string & sKey, + std::string & sValue, + uint64_t & llVersion); + + PhxKVStatus Delete( + const std::string & sKey, + const uint64_t llVersion = NullVersion); + +private: + int GetGroupIdx(const std::string & sKey); + + int KVPropose(const std::string & sKey, const std::string & sPaxosValue, PhxKVSMCtx & oPhxKVSMCtx); + +private: + phxpaxos::NodeInfo m_oMyNode; + phxpaxos::NodeInfoList m_vecNodeList; + std::string m_sKVDBPath; + std::string m_sPaxosLogPath; + + int m_iGroupCount; + phxpaxos::Node * m_poPaxosNode; + PhxKVSM m_oPhxKVSM; +}; + +} + + diff --git a/sample/phxkv/kvsm.cpp b/sample/phxkv/kvsm.cpp new file mode 100644 index 000000000..c720922b5 --- /dev/null +++ b/sample/phxkv/kvsm.cpp @@ -0,0 +1,201 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "kvsm.h" +#include "phxkv.pb.h" +#include "log.h" +#include + +using namespace phxpaxos; +using namespace std; + +namespace phxkv +{ + +PhxKVSM :: PhxKVSM(const std::string & sDBPath) + : m_llCheckpointInstanceID(phxpaxos::NoCheckpoint), m_iSkipSyncCheckpointTimes(0) +{ + m_sDBPath = sDBPath; +} + +PhxKVSM :: ~PhxKVSM() +{ +} + +const bool PhxKVSM :: Init() +{ + bool bSucc = m_oKVClient.Init(m_sDBPath); + if (!bSucc) + { + PLErr("KVClient.Init fail, dbpath %s", m_sDBPath.c_str()); + return false; + } + + int ret = m_oKVClient.GetCheckpointInstanceID(m_llCheckpointInstanceID); + if (ret != 0 && ret != KVCLIENT_KEY_NOTEXIST) + { + PLErr("KVClient.GetCheckpointInstanceID fail, ret %d", ret); + return false; + } + + if (ret == KVCLIENT_KEY_NOTEXIST) + { + PLImp("no checkpoint"); + m_llCheckpointInstanceID = phxpaxos::NoCheckpoint; + } + else + { + PLImp("CheckpointInstanceID %lu", m_llCheckpointInstanceID); + } + + return true; +} + +int PhxKVSM :: SyncCheckpointInstanceID(const uint64_t llInstanceID) +{ + if (m_iSkipSyncCheckpointTimes++ < 5) + { + PLDebug("no need to sync checkpoint, skiptimes %d", m_iSkipSyncCheckpointTimes); + return 0; + } + + int ret = m_oKVClient.SetCheckpointInstanceID(llInstanceID); + if (ret != 0) + { + PLErr("KVClient::SetCheckpointInstanceID fail, ret %d instanceid %lu", ret, llInstanceID); + return ret; + } + + PLImp("ok, old checkpoint instanceid %lu new checkpoint instanceid %lu", + m_llCheckpointInstanceID, llInstanceID); + + m_llCheckpointInstanceID = llInstanceID; + m_iSkipSyncCheckpointTimes = 0; + + return 0; +} + +bool PhxKVSM :: Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, SMCtx * poSMCtx) +{ + KVOperator oKVOper; + bool bSucc = oKVOper.ParseFromArray(sPaxosValue.data(), sPaxosValue.size()); + if (!bSucc) + { + PLErr("oKVOper data wrong"); + //wrong oper data, just skip, so return true + return true; + } + + int iExecuteRet = -1; + string sReadValue; + uint64_t llReadVersion; + + if (oKVOper.operator_() == KVOperatorType_READ) + { + iExecuteRet = m_oKVClient.Get(oKVOper.key(), sReadValue, llReadVersion); + } + else if (oKVOper.operator_() == KVOperatorType_WRITE) + { + iExecuteRet = m_oKVClient.Set(oKVOper.key(), oKVOper.value(), oKVOper.version()); + } + else if (oKVOper.operator_() == KVOperatorType_DELETE) + { + iExecuteRet = m_oKVClient.Del(oKVOper.key(), oKVOper.version()); + } + else + { + PLErr("unknown op %u", oKVOper.operator_()); + //wrong op, just skip, so return true; + return true; + } + + if (iExecuteRet == KVCLIENT_SYS_FAIL) + { + //need retry + return false; + } + else + { + if (poSMCtx != nullptr && poSMCtx->m_pCtx != nullptr) + { + PhxKVSMCtx * poPhxKVSMCtx = (PhxKVSMCtx *)poSMCtx->m_pCtx; + poPhxKVSMCtx->iExecuteRet = iExecuteRet; + poPhxKVSMCtx->sReadValue = sReadValue; + poPhxKVSMCtx->llReadVersion = llReadVersion; + } + + SyncCheckpointInstanceID(llInstanceID); + + return true; + } +} + +//////////////////////////////////////////////////// + +bool PhxKVSM :: MakeOpValue( + const std::string & sKey, + const std::string & sValue, + const uint64_t llVersion, + const KVOperatorType iOp, + std::string & sPaxosValue) +{ + KVOperator oKVOper; + oKVOper.set_key(sKey); + oKVOper.set_value(sValue); + oKVOper.set_version(llVersion); + oKVOper.set_operator_(iOp); + oKVOper.set_sid(rand()); + + return oKVOper.SerializeToString(&sPaxosValue); +} + +bool PhxKVSM :: MakeGetOpValue( + const std::string & sKey, + std::string & sPaxosValue) +{ + return MakeOpValue(sKey, "", 0, KVOperatorType_READ, sPaxosValue); +} + +bool PhxKVSM :: MakeSetOpValue( + const std::string & sKey, + const std::string & sValue, + const uint64_t llVersion, + std::string & sPaxosValue) +{ + return MakeOpValue(sKey, sValue, llVersion, KVOperatorType_WRITE, sPaxosValue); +} + +bool PhxKVSM :: MakeDelOpValue( + const std::string & sKey, + const uint64_t llVersion, + std::string & sPaxosValue) +{ + return MakeOpValue(sKey, "", llVersion, KVOperatorType_DELETE, sPaxosValue); +} + +KVClient * PhxKVSM :: GetKVClient() +{ + return &m_oKVClient; +} + +} + diff --git a/sample/phxkv/kvsm.h b/sample/phxkv/kvsm.h new file mode 100644 index 000000000..580bc5698 --- /dev/null +++ b/sample/phxkv/kvsm.h @@ -0,0 +1,116 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/sm.h" +#include "kv.h" +#include +#include "def.h" + +namespace phxkv +{ + +class PhxKVSMCtx +{ +public: + int iExecuteRet; + std::string sReadValue; + uint64_t llReadVersion; + + PhxKVSMCtx() + { + iExecuteRet = -1; + llReadVersion = 0; + } +}; + +//////////////////////////////////////////////// + +class PhxKVSM : public phxpaxos::StateMachine +{ +public: + PhxKVSM(const std::string & sDBPath); + ~PhxKVSM(); + + const bool Init(); + + bool Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, phxpaxos::SMCtx * poSMCtx); + + const int SMID() const {return 1;} + +public: + //no use + bool ExecuteForCheckpoint(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue) {return true;} + + //have checkpoint. + const uint64_t GetCheckpointInstanceID(const int iGroupIdx) const { return m_llCheckpointInstanceID;} + +public: + //have checkpoint, but not impl auto copy checkpoint to other node, so return fail. + int LockCheckpointState() { return -1; } + + int GetCheckpointState(const int iGroupIdx, std::string & sDirPath, + std::vector & vecFileList) { return -1; } + + void UnLockCheckpointState() { } + + int LoadCheckpointState(const int iGroupIdx, const std::string & sCheckpointTmpFileDirPath, + const std::vector & vecFileList, const uint64_t llCheckpointInstanceID) { return -1; } + +public: + static bool MakeOpValue( + const std::string & sKey, + const std::string & sValue, + const uint64_t llVersion, + const KVOperatorType iOp, + std::string & sPaxosValue); + + static bool MakeGetOpValue( + const std::string & sKey, + std::string & sPaxosValue); + + static bool MakeSetOpValue( + const std::string & sKey, + const std::string & sValue, + const uint64_t llVersion, + std::string & sPaxosValue); + + static bool MakeDelOpValue( + const std::string & sKey, + const uint64_t llVersion, + std::string & sPaxosValue); + + KVClient * GetKVClient(); + + int SyncCheckpointInstanceID(const uint64_t llInstanceID); + +private: + std::string m_sDBPath; + KVClient m_oKVClient; + + uint64_t m_llCheckpointInstanceID; + int m_iSkipSyncCheckpointTimes; +}; + +} diff --git a/sample/phxkv/log.cpp b/sample/phxkv/log.cpp new file mode 100644 index 000000000..4eeee6503 --- /dev/null +++ b/sample/phxkv/log.cpp @@ -0,0 +1,63 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "log.h" + +using namespace phxpaxos; + +namespace phxkv +{ + +LoggerGuard :: LoggerGuard() + : m_pLogFunc(nullptr) +{ +} + +LoggerGuard :: ~LoggerGuard() +{ +} + +LoggerGuard * LoggerGuard :: Instance() +{ + static LoggerGuard oLoggerGuard; + return &oLoggerGuard; +} + +int LoggerGuard :: Init(const std::string & sModuleName, const std::string & sLogPath, const int iLogLevel) +{ + int ret = LoggerGoogle :: GetLogger(sModuleName, sLogPath, iLogLevel, m_pLogFunc); + if (ret != 0) + { + printf("get logger_google fail, ret %d\n", ret); + return ret; + } + + return 0; +} + +phxpaxos::LogFunc LoggerGuard :: GetLogFunc() +{ + return m_pLogFunc; +} + + +} + diff --git a/sample/phxkv/log.h b/sample/phxkv/log.h new file mode 100644 index 000000000..516b0358e --- /dev/null +++ b/sample/phxkv/log.h @@ -0,0 +1,65 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos_plugin/logger_google.h" +#include +#include + +namespace phxkv +{ + +#define LOGGER (LoggerGuard::Instance()) +#define LOG_ERROR(format, args...)\ + if (LOGGER->GetLogFunc() != nullptr)phxpaxos::LoggerGoogle::LogError(format, ## args); +#define LOG_WARNING(format, args...)\ + if (LOGGER->GetLogFunc() != nullptr)phxpaxos::LoggerGoogle::LogWarning(format, ## args); +#define LOG_INFO(format, args...)\ + if (LOGGER->GetLogFunc() != nullptr)phxpaxos::LoggerGoogle::LogInfo(format, ## args); +#define LOG_VERBOSE(format, args...)\ + if (LOGGER->GetLogFunc() != nullptr)phxpaxos::LoggerGoogle::LogVerbose(format, ## args); + +#define NLDebug(format, args...) LOG_VERBOSE("DEBUG: %s " format, __func__, ## args); +#define NLErr(format, args...) LOG_ERROR("ERR: %s " format, __func__, ## args); + +#define PLErr(format, args...) LOG_ERROR("ERR: %s::%s " format, typeid(this).name(), __func__, ## args); +#define PLImp(format, args...) LOG_INFO("Showy: %s::%s " format, typeid(this).name(), __func__, ## args); +#define PLHead(format, args...) LOG_WARNING("Imp: %s::%s " format, typeid(this).name(), __func__, ## args); +#define PLDebug(format, args...) LOG_VERBOSE("DEBUG: %s::%s " format, typeid(this).name(), __func__, ## args); + +class LoggerGuard +{ +public: + LoggerGuard(); + ~LoggerGuard(); + + int Init(const std::string & sModuleName, const std::string & sLogPath, const int iLogLevel); + + static LoggerGuard * Instance(); + + phxpaxos::LogFunc GetLogFunc(); + +private: + phxpaxos::LogFunc m_pLogFunc; +}; + +} diff --git a/sample/phxkv/phxkv.grpc.pb.cc b/sample/phxkv/phxkv.grpc.pb.cc new file mode 100644 index 000000000..2e6817a1a --- /dev/null +++ b/sample/phxkv/phxkv.grpc.pb.cc @@ -0,0 +1,126 @@ +// Generated by the gRPC protobuf plugin. +// If you make any local change, they will be lost. +// source: phxkv.proto + +#include "phxkv.pb.h" +#include "phxkv.grpc.pb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +namespace phxkv { + +static const char* PhxKVServer_method_names[] = { + "/phxkv.PhxKVServer/Put", + "/phxkv.PhxKVServer/GetLocal", + "/phxkv.PhxKVServer/GetGlobal", + "/phxkv.PhxKVServer/Delete", +}; + +std::unique_ptr< PhxKVServer::Stub> PhxKVServer::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) { + std::unique_ptr< PhxKVServer::Stub> stub(new PhxKVServer::Stub(channel)); + return stub; +} + +PhxKVServer::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel) + : channel_(channel), rpcmethod_Put_(PhxKVServer_method_names[0], ::grpc::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_GetLocal_(PhxKVServer_method_names[1], ::grpc::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_GetGlobal_(PhxKVServer_method_names[2], ::grpc::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_Delete_(PhxKVServer_method_names[3], ::grpc::RpcMethod::NORMAL_RPC, channel) + {} + +::grpc::Status PhxKVServer::Stub::Put(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) { + return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_Put_, context, request, response); +} + +::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>* PhxKVServer::Stub::AsyncPutRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return new ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>(channel_.get(), cq, rpcmethod_Put_, context, request); +} + +::grpc::Status PhxKVServer::Stub::GetLocal(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) { + return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_GetLocal_, context, request, response); +} + +::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>* PhxKVServer::Stub::AsyncGetLocalRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return new ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>(channel_.get(), cq, rpcmethod_GetLocal_, context, request); +} + +::grpc::Status PhxKVServer::Stub::GetGlobal(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) { + return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_GetGlobal_, context, request, response); +} + +::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>* PhxKVServer::Stub::AsyncGetGlobalRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return new ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>(channel_.get(), cq, rpcmethod_GetGlobal_, context, request); +} + +::grpc::Status PhxKVServer::Stub::Delete(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) { + return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_Delete_, context, request, response); +} + +::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>* PhxKVServer::Stub::AsyncDeleteRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return new ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>(channel_.get(), cq, rpcmethod_Delete_, context, request); +} + +PhxKVServer::Service::Service() { + (void)PhxKVServer_method_names; + AddMethod(new ::grpc::RpcServiceMethod( + PhxKVServer_method_names[0], + ::grpc::RpcMethod::NORMAL_RPC, + new ::grpc::RpcMethodHandler< PhxKVServer::Service, ::phxkv::KVOperator, ::phxkv::KVResponse>( + std::mem_fn(&PhxKVServer::Service::Put), this))); + AddMethod(new ::grpc::RpcServiceMethod( + PhxKVServer_method_names[1], + ::grpc::RpcMethod::NORMAL_RPC, + new ::grpc::RpcMethodHandler< PhxKVServer::Service, ::phxkv::KVOperator, ::phxkv::KVResponse>( + std::mem_fn(&PhxKVServer::Service::GetLocal), this))); + AddMethod(new ::grpc::RpcServiceMethod( + PhxKVServer_method_names[2], + ::grpc::RpcMethod::NORMAL_RPC, + new ::grpc::RpcMethodHandler< PhxKVServer::Service, ::phxkv::KVOperator, ::phxkv::KVResponse>( + std::mem_fn(&PhxKVServer::Service::GetGlobal), this))); + AddMethod(new ::grpc::RpcServiceMethod( + PhxKVServer_method_names[3], + ::grpc::RpcMethod::NORMAL_RPC, + new ::grpc::RpcMethodHandler< PhxKVServer::Service, ::phxkv::KVOperator, ::phxkv::KVResponse>( + std::mem_fn(&PhxKVServer::Service::Delete), this))); +} + +PhxKVServer::Service::~Service() { +} + +::grpc::Status PhxKVServer::Service::Put(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) { + (void) context; + (void) request; + (void) response; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + +::grpc::Status PhxKVServer::Service::GetLocal(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) { + (void) context; + (void) request; + (void) response; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + +::grpc::Status PhxKVServer::Service::GetGlobal(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) { + (void) context; + (void) request; + (void) response; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + +::grpc::Status PhxKVServer::Service::Delete(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) { + (void) context; + (void) request; + (void) response; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + + +} // namespace phxkv + diff --git a/sample/phxkv/phxkv.grpc.pb.h b/sample/phxkv/phxkv.grpc.pb.h new file mode 100644 index 000000000..a7b9830fe --- /dev/null +++ b/sample/phxkv/phxkv.grpc.pb.h @@ -0,0 +1,251 @@ +// Generated by the gRPC protobuf plugin. +// If you make any local change, they will be lost. +// source: phxkv.proto +#ifndef GRPC_phxkv_2eproto__INCLUDED +#define GRPC_phxkv_2eproto__INCLUDED + +#include "phxkv.pb.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { +class CompletionQueue; +class Channel; +class RpcService; +class ServerCompletionQueue; +class ServerContext; +} // namespace grpc + +namespace phxkv { + +class PhxKVServer GRPC_FINAL { + public: + class StubInterface { + public: + virtual ~StubInterface() {} + virtual ::grpc::Status Put(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>> AsyncPut(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>>(AsyncPutRaw(context, request, cq)); + } + virtual ::grpc::Status GetLocal(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>> AsyncGetLocal(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>>(AsyncGetLocalRaw(context, request, cq)); + } + virtual ::grpc::Status GetGlobal(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>> AsyncGetGlobal(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>>(AsyncGetGlobalRaw(context, request, cq)); + } + virtual ::grpc::Status Delete(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>> AsyncDelete(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>>(AsyncDeleteRaw(context, request, cq)); + } + private: + virtual ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>* AsyncPutRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>* AsyncGetLocalRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>* AsyncGetGlobalRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::phxkv::KVResponse>* AsyncDeleteRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) = 0; + }; + class Stub GRPC_FINAL : public StubInterface { + public: + Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); + ::grpc::Status Put(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) GRPC_OVERRIDE; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>> AsyncPut(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>>(AsyncPutRaw(context, request, cq)); + } + ::grpc::Status GetLocal(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) GRPC_OVERRIDE; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>> AsyncGetLocal(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>>(AsyncGetLocalRaw(context, request, cq)); + } + ::grpc::Status GetGlobal(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) GRPC_OVERRIDE; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>> AsyncGetGlobal(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>>(AsyncGetGlobalRaw(context, request, cq)); + } + ::grpc::Status Delete(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::phxkv::KVResponse* response) GRPC_OVERRIDE; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>> AsyncDelete(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>>(AsyncDeleteRaw(context, request, cq)); + } + + private: + std::shared_ptr< ::grpc::ChannelInterface> channel_; + ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>* AsyncPutRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) GRPC_OVERRIDE; + ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>* AsyncGetLocalRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) GRPC_OVERRIDE; + ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>* AsyncGetGlobalRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) GRPC_OVERRIDE; + ::grpc::ClientAsyncResponseReader< ::phxkv::KVResponse>* AsyncDeleteRaw(::grpc::ClientContext* context, const ::phxkv::KVOperator& request, ::grpc::CompletionQueue* cq) GRPC_OVERRIDE; + const ::grpc::RpcMethod rpcmethod_Put_; + const ::grpc::RpcMethod rpcmethod_GetLocal_; + const ::grpc::RpcMethod rpcmethod_GetGlobal_; + const ::grpc::RpcMethod rpcmethod_Delete_; + }; + static std::unique_ptr NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); + + class Service : public ::grpc::Service { + public: + Service(); + virtual ~Service(); + virtual ::grpc::Status Put(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response); + virtual ::grpc::Status GetLocal(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response); + virtual ::grpc::Status GetGlobal(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response); + virtual ::grpc::Status Delete(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response); + }; + template + class WithAsyncMethod_Put : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(Service *service) {} + public: + WithAsyncMethod_Put() { + ::grpc::Service::MarkMethodAsync(0); + } + ~WithAsyncMethod_Put() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status Put(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestPut(::grpc::ServerContext* context, ::phxkv::KVOperator* request, ::grpc::ServerAsyncResponseWriter< ::phxkv::KVResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag); + } + }; + template + class WithAsyncMethod_GetLocal : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(Service *service) {} + public: + WithAsyncMethod_GetLocal() { + ::grpc::Service::MarkMethodAsync(1); + } + ~WithAsyncMethod_GetLocal() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status GetLocal(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestGetLocal(::grpc::ServerContext* context, ::phxkv::KVOperator* request, ::grpc::ServerAsyncResponseWriter< ::phxkv::KVResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag); + } + }; + template + class WithAsyncMethod_GetGlobal : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(Service *service) {} + public: + WithAsyncMethod_GetGlobal() { + ::grpc::Service::MarkMethodAsync(2); + } + ~WithAsyncMethod_GetGlobal() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status GetGlobal(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestGetGlobal(::grpc::ServerContext* context, ::phxkv::KVOperator* request, ::grpc::ServerAsyncResponseWriter< ::phxkv::KVResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(2, context, request, response, new_call_cq, notification_cq, tag); + } + }; + template + class WithAsyncMethod_Delete : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(Service *service) {} + public: + WithAsyncMethod_Delete() { + ::grpc::Service::MarkMethodAsync(3); + } + ~WithAsyncMethod_Delete() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status Delete(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestDelete(::grpc::ServerContext* context, ::phxkv::KVOperator* request, ::grpc::ServerAsyncResponseWriter< ::phxkv::KVResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(3, context, request, response, new_call_cq, notification_cq, tag); + } + }; + typedef WithAsyncMethod_Put > > > AsyncService; + template + class WithGenericMethod_Put : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(Service *service) {} + public: + WithGenericMethod_Put() { + ::grpc::Service::MarkMethodGeneric(0); + } + ~WithGenericMethod_Put() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status Put(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithGenericMethod_GetLocal : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(Service *service) {} + public: + WithGenericMethod_GetLocal() { + ::grpc::Service::MarkMethodGeneric(1); + } + ~WithGenericMethod_GetLocal() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status GetLocal(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithGenericMethod_GetGlobal : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(Service *service) {} + public: + WithGenericMethod_GetGlobal() { + ::grpc::Service::MarkMethodGeneric(2); + } + ~WithGenericMethod_GetGlobal() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status GetGlobal(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithGenericMethod_Delete : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(Service *service) {} + public: + WithGenericMethod_Delete() { + ::grpc::Service::MarkMethodGeneric(3); + } + ~WithGenericMethod_Delete() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status Delete(::grpc::ServerContext* context, const ::phxkv::KVOperator* request, ::phxkv::KVResponse* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; +}; + +} // namespace phxkv + + +#endif // GRPC_phxkv_2eproto__INCLUDED diff --git a/sample/phxkv/phxkv.pb.cc b/sample/phxkv/phxkv.pb.cc new file mode 100644 index 000000000..9755254dc --- /dev/null +++ b/sample/phxkv/phxkv.pb.cc @@ -0,0 +1,1446 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: phxkv.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "phxkv.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace phxkv { + +namespace { + +const ::google::protobuf::Descriptor* KVOperator_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + KVOperator_reflection_ = NULL; +const ::google::protobuf::Descriptor* KVData_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + KVData_reflection_ = NULL; +const ::google::protobuf::Descriptor* KVResponse_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + KVResponse_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_phxkv_2eproto() { + protobuf_AddDesc_phxkv_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "phxkv.proto"); + GOOGLE_CHECK(file != NULL); + KVOperator_descriptor_ = file->message_type(0); + static const int KVOperator_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVOperator, key_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVOperator, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVOperator, version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVOperator, operator__), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVOperator, sid_), + }; + KVOperator_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + KVOperator_descriptor_, + KVOperator::default_instance_, + KVOperator_offsets_, + -1, + -1, + -1, + sizeof(KVOperator), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVOperator, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVOperator, _is_default_instance_)); + KVData_descriptor_ = file->message_type(1); + static const int KVData_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVData, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVData, version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVData, isdeleted_), + }; + KVData_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + KVData_descriptor_, + KVData::default_instance_, + KVData_offsets_, + -1, + -1, + -1, + sizeof(KVData), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVData, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVData, _is_default_instance_)); + KVResponse_descriptor_ = file->message_type(2); + static const int KVResponse_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVResponse, data_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVResponse, ret_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVResponse, master_nodeid_), + }; + KVResponse_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + KVResponse_descriptor_, + KVResponse::default_instance_, + KVResponse_offsets_, + -1, + -1, + -1, + sizeof(KVResponse), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVResponse, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(KVResponse, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_phxkv_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + KVOperator_descriptor_, &KVOperator::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + KVData_descriptor_, &KVData::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + KVResponse_descriptor_, &KVResponse::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_phxkv_2eproto() { + delete KVOperator::default_instance_; + delete KVOperator_reflection_; + delete KVData::default_instance_; + delete KVData_reflection_; + delete KVResponse::default_instance_; + delete KVResponse_reflection_; +} + +void protobuf_AddDesc_phxkv_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\013phxkv.proto\022\005phxkv\"X\n\nKVOperator\022\013\n\003ke" + "y\030\001 \001(\t\022\r\n\005value\030\002 \001(\014\022\017\n\007version\030\003 \001(\004\022" + "\020\n\010operator\030\004 \001(\r\022\013\n\003sid\030\005 \001(\r\";\n\006KVData" + "\022\r\n\005value\030\001 \001(\014\022\017\n\007version\030\002 \001(\004\022\021\n\tisde" + "leted\030\003 \001(\010\"M\n\nKVResponse\022\033\n\004data\030\001 \001(\0132" + "\r.phxkv.KVData\022\013\n\003ret\030\002 \001(\005\022\025\n\rmaster_no" + "deid\030\003 \001(\0042\327\001\n\013PhxKVServer\022-\n\003Put\022\021.phxk" + "v.KVOperator\032\021.phxkv.KVResponse\"\000\0222\n\010Get" + "Local\022\021.phxkv.KVOperator\032\021.phxkv.KVRespo" + "nse\"\000\0223\n\tGetGlobal\022\021.phxkv.KVOperator\032\021." + "phxkv.KVResponse\"\000\0220\n\006Delete\022\021.phxkv.KVO" + "perator\032\021.phxkv.KVResponse\"\000b\006proto3", 476); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "phxkv.proto", &protobuf_RegisterTypes); + KVOperator::default_instance_ = new KVOperator(); + KVData::default_instance_ = new KVData(); + KVResponse::default_instance_ = new KVResponse(); + KVOperator::default_instance_->InitAsDefaultInstance(); + KVData::default_instance_->InitAsDefaultInstance(); + KVResponse::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_phxkv_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_phxkv_2eproto { + StaticDescriptorInitializer_phxkv_2eproto() { + protobuf_AddDesc_phxkv_2eproto(); + } +} static_descriptor_initializer_phxkv_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int KVOperator::kKeyFieldNumber; +const int KVOperator::kValueFieldNumber; +const int KVOperator::kVersionFieldNumber; +const int KVOperator::kOperatorFieldNumber; +const int KVOperator::kSidFieldNumber; +#endif // !_MSC_VER + +KVOperator::KVOperator() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxkv.KVOperator) +} + +void KVOperator::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +KVOperator::KVOperator(const KVOperator& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxkv.KVOperator) +} + +void KVOperator::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + key_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + version_ = GOOGLE_ULONGLONG(0); + operator__ = 0u; + sid_ = 0u; +} + +KVOperator::~KVOperator() { + // @@protoc_insertion_point(destructor:phxkv.KVOperator) + SharedDtor(); +} + +void KVOperator::SharedDtor() { + key_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void KVOperator::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* KVOperator::descriptor() { + protobuf_AssignDescriptorsOnce(); + return KVOperator_descriptor_; +} + +const KVOperator& KVOperator::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_phxkv_2eproto(); + return *default_instance_; +} + +KVOperator* KVOperator::default_instance_ = NULL; + +KVOperator* KVOperator::New(::google::protobuf::Arena* arena) const { + KVOperator* n = new KVOperator; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void KVOperator::Clear() { +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(version_, sid_); + key_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + +#undef ZR_HELPER_ +#undef ZR_ + +} + +bool KVOperator::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxkv.KVOperator) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string key = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_key())); + DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->key().data(), this->key().length(), + ::google::protobuf::internal::WireFormatLite::PARSE, + "phxkv.KVOperator.key")); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_value; + break; + } + + // optional bytes value = 2; + case 2: { + if (tag == 18) { + parse_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_value())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_version; + break; + } + + // optional uint64 version = 3; + case 3: { + if (tag == 24) { + parse_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &version_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_operator; + break; + } + + // optional uint32 operator = 4; + case 4: { + if (tag == 32) { + parse_operator: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &operator__))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_sid; + break; + } + + // optional uint32 sid = 5; + case 5: { + if (tag == 40) { + parse_sid: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &sid_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxkv.KVOperator) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxkv.KVOperator) + return false; +#undef DO_ +} + +void KVOperator::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxkv.KVOperator) + // optional string key = 1; + if (this->key().size() > 0) { + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->key().data(), this->key().length(), + ::google::protobuf::internal::WireFormatLite::SERIALIZE, + "phxkv.KVOperator.key"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->key(), output); + } + + // optional bytes value = 2; + if (this->value().size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 2, this->value(), output); + } + + // optional uint64 version = 3; + if (this->version() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->version(), output); + } + + // optional uint32 operator = 4; + if (this->operator_() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->operator_(), output); + } + + // optional uint32 sid = 5; + if (this->sid() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->sid(), output); + } + + // @@protoc_insertion_point(serialize_end:phxkv.KVOperator) +} + +::google::protobuf::uint8* KVOperator::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxkv.KVOperator) + // optional string key = 1; + if (this->key().size() > 0) { + ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( + this->key().data(), this->key().length(), + ::google::protobuf::internal::WireFormatLite::SERIALIZE, + "phxkv.KVOperator.key"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->key(), target); + } + + // optional bytes value = 2; + if (this->value().size() > 0) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 2, this->value(), target); + } + + // optional uint64 version = 3; + if (this->version() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->version(), target); + } + + // optional uint32 operator = 4; + if (this->operator_() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->operator_(), target); + } + + // optional uint32 sid = 5; + if (this->sid() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->sid(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:phxkv.KVOperator) + return target; +} + +int KVOperator::ByteSize() const { + int total_size = 0; + + // optional string key = 1; + if (this->key().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->key()); + } + + // optional bytes value = 2; + if (this->value().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->value()); + } + + // optional uint64 version = 3; + if (this->version() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->version()); + } + + // optional uint32 operator = 4; + if (this->operator_() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->operator_()); + } + + // optional uint32 sid = 5; + if (this->sid() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->sid()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void KVOperator::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const KVOperator* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void KVOperator::MergeFrom(const KVOperator& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.key().size() > 0) { + + key_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.key_); + } + if (from.value().size() > 0) { + + value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_); + } + if (from.version() != 0) { + set_version(from.version()); + } + if (from.operator_() != 0) { + set_operator_(from.operator_()); + } + if (from.sid() != 0) { + set_sid(from.sid()); + } +} + +void KVOperator::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void KVOperator::CopyFrom(const KVOperator& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool KVOperator::IsInitialized() const { + + return true; +} + +void KVOperator::Swap(KVOperator* other) { + if (other == this) return; + InternalSwap(other); +} +void KVOperator::InternalSwap(KVOperator* other) { + key_.Swap(&other->key_); + value_.Swap(&other->value_); + std::swap(version_, other->version_); + std::swap(operator__, other->operator__); + std::swap(sid_, other->sid_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata KVOperator::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = KVOperator_descriptor_; + metadata.reflection = KVOperator_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// KVOperator + +// optional string key = 1; +void KVOperator::clear_key() { + key_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& KVOperator::key() const { + // @@protoc_insertion_point(field_get:phxkv.KVOperator.key) + return key_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void KVOperator::set_key(const ::std::string& value) { + + key_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxkv.KVOperator.key) +} + void KVOperator::set_key(const char* value) { + + key_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxkv.KVOperator.key) +} + void KVOperator::set_key(const char* value, size_t size) { + + key_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxkv.KVOperator.key) +} + ::std::string* KVOperator::mutable_key() { + + // @@protoc_insertion_point(field_mutable:phxkv.KVOperator.key) + return key_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* KVOperator::release_key() { + + return key_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void KVOperator::set_allocated_key(::std::string* key) { + if (key != NULL) { + + } else { + + } + key_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), key); + // @@protoc_insertion_point(field_set_allocated:phxkv.KVOperator.key) +} + +// optional bytes value = 2; +void KVOperator::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& KVOperator::value() const { + // @@protoc_insertion_point(field_get:phxkv.KVOperator.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void KVOperator::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxkv.KVOperator.value) +} + void KVOperator::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxkv.KVOperator.value) +} + void KVOperator::set_value(const void* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxkv.KVOperator.value) +} + ::std::string* KVOperator::mutable_value() { + + // @@protoc_insertion_point(field_mutable:phxkv.KVOperator.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* KVOperator::release_value() { + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void KVOperator::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:phxkv.KVOperator.value) +} + +// optional uint64 version = 3; +void KVOperator::clear_version() { + version_ = GOOGLE_ULONGLONG(0); +} + ::google::protobuf::uint64 KVOperator::version() const { + // @@protoc_insertion_point(field_get:phxkv.KVOperator.version) + return version_; +} + void KVOperator::set_version(::google::protobuf::uint64 value) { + + version_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVOperator.version) +} + +// optional uint32 operator = 4; +void KVOperator::clear_operator_() { + operator__ = 0u; +} + ::google::protobuf::uint32 KVOperator::operator_() const { + // @@protoc_insertion_point(field_get:phxkv.KVOperator.operator) + return operator__; +} + void KVOperator::set_operator_(::google::protobuf::uint32 value) { + + operator__ = value; + // @@protoc_insertion_point(field_set:phxkv.KVOperator.operator) +} + +// optional uint32 sid = 5; +void KVOperator::clear_sid() { + sid_ = 0u; +} + ::google::protobuf::uint32 KVOperator::sid() const { + // @@protoc_insertion_point(field_get:phxkv.KVOperator.sid) + return sid_; +} + void KVOperator::set_sid(::google::protobuf::uint32 value) { + + sid_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVOperator.sid) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int KVData::kValueFieldNumber; +const int KVData::kVersionFieldNumber; +const int KVData::kIsdeletedFieldNumber; +#endif // !_MSC_VER + +KVData::KVData() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxkv.KVData) +} + +void KVData::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +KVData::KVData(const KVData& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxkv.KVData) +} + +void KVData::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + version_ = GOOGLE_ULONGLONG(0); + isdeleted_ = false; +} + +KVData::~KVData() { + // @@protoc_insertion_point(destructor:phxkv.KVData) + SharedDtor(); +} + +void KVData::SharedDtor() { + value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void KVData::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* KVData::descriptor() { + protobuf_AssignDescriptorsOnce(); + return KVData_descriptor_; +} + +const KVData& KVData::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_phxkv_2eproto(); + return *default_instance_; +} + +KVData* KVData::default_instance_ = NULL; + +KVData* KVData::New(::google::protobuf::Arena* arena) const { + KVData* n = new KVData; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void KVData::Clear() { +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(version_, isdeleted_); + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + +#undef ZR_HELPER_ +#undef ZR_ + +} + +bool KVData::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxkv.KVData) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional bytes value = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_value())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_version; + break; + } + + // optional uint64 version = 2; + case 2: { + if (tag == 16) { + parse_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &version_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_isdeleted; + break; + } + + // optional bool isdeleted = 3; + case 3: { + if (tag == 24) { + parse_isdeleted: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &isdeleted_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxkv.KVData) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxkv.KVData) + return false; +#undef DO_ +} + +void KVData::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxkv.KVData) + // optional bytes value = 1; + if (this->value().size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 1, this->value(), output); + } + + // optional uint64 version = 2; + if (this->version() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->version(), output); + } + + // optional bool isdeleted = 3; + if (this->isdeleted() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->isdeleted(), output); + } + + // @@protoc_insertion_point(serialize_end:phxkv.KVData) +} + +::google::protobuf::uint8* KVData::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxkv.KVData) + // optional bytes value = 1; + if (this->value().size() > 0) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 1, this->value(), target); + } + + // optional uint64 version = 2; + if (this->version() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->version(), target); + } + + // optional bool isdeleted = 3; + if (this->isdeleted() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->isdeleted(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:phxkv.KVData) + return target; +} + +int KVData::ByteSize() const { + int total_size = 0; + + // optional bytes value = 1; + if (this->value().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->value()); + } + + // optional uint64 version = 2; + if (this->version() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->version()); + } + + // optional bool isdeleted = 3; + if (this->isdeleted() != 0) { + total_size += 1 + 1; + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void KVData::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const KVData* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void KVData::MergeFrom(const KVData& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.value().size() > 0) { + + value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_); + } + if (from.version() != 0) { + set_version(from.version()); + } + if (from.isdeleted() != 0) { + set_isdeleted(from.isdeleted()); + } +} + +void KVData::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void KVData::CopyFrom(const KVData& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool KVData::IsInitialized() const { + + return true; +} + +void KVData::Swap(KVData* other) { + if (other == this) return; + InternalSwap(other); +} +void KVData::InternalSwap(KVData* other) { + value_.Swap(&other->value_); + std::swap(version_, other->version_); + std::swap(isdeleted_, other->isdeleted_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata KVData::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = KVData_descriptor_; + metadata.reflection = KVData_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// KVData + +// optional bytes value = 1; +void KVData::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& KVData::value() const { + // @@protoc_insertion_point(field_get:phxkv.KVData.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void KVData::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxkv.KVData.value) +} + void KVData::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxkv.KVData.value) +} + void KVData::set_value(const void* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxkv.KVData.value) +} + ::std::string* KVData::mutable_value() { + + // @@protoc_insertion_point(field_mutable:phxkv.KVData.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* KVData::release_value() { + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void KVData::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:phxkv.KVData.value) +} + +// optional uint64 version = 2; +void KVData::clear_version() { + version_ = GOOGLE_ULONGLONG(0); +} + ::google::protobuf::uint64 KVData::version() const { + // @@protoc_insertion_point(field_get:phxkv.KVData.version) + return version_; +} + void KVData::set_version(::google::protobuf::uint64 value) { + + version_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVData.version) +} + +// optional bool isdeleted = 3; +void KVData::clear_isdeleted() { + isdeleted_ = false; +} + bool KVData::isdeleted() const { + // @@protoc_insertion_point(field_get:phxkv.KVData.isdeleted) + return isdeleted_; +} + void KVData::set_isdeleted(bool value) { + + isdeleted_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVData.isdeleted) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int KVResponse::kDataFieldNumber; +const int KVResponse::kRetFieldNumber; +const int KVResponse::kMasterNodeidFieldNumber; +#endif // !_MSC_VER + +KVResponse::KVResponse() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxkv.KVResponse) +} + +void KVResponse::InitAsDefaultInstance() { + _is_default_instance_ = true; + data_ = const_cast< ::phxkv::KVData*>(&::phxkv::KVData::default_instance()); +} + +KVResponse::KVResponse(const KVResponse& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxkv.KVResponse) +} + +void KVResponse::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + data_ = NULL; + ret_ = 0; + master_nodeid_ = GOOGLE_ULONGLONG(0); +} + +KVResponse::~KVResponse() { + // @@protoc_insertion_point(destructor:phxkv.KVResponse) + SharedDtor(); +} + +void KVResponse::SharedDtor() { + if (this != default_instance_) { + delete data_; + } +} + +void KVResponse::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* KVResponse::descriptor() { + protobuf_AssignDescriptorsOnce(); + return KVResponse_descriptor_; +} + +const KVResponse& KVResponse::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_phxkv_2eproto(); + return *default_instance_; +} + +KVResponse* KVResponse::default_instance_ = NULL; + +KVResponse* KVResponse::New(::google::protobuf::Arena* arena) const { + KVResponse* n = new KVResponse; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void KVResponse::Clear() { +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(master_nodeid_, ret_); + if (GetArenaNoVirtual() == NULL && data_ != NULL) delete data_; + data_ = NULL; + +#undef ZR_HELPER_ +#undef ZR_ + +} + +bool KVResponse::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxkv.KVResponse) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .phxkv.KVData data = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_data())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_ret; + break; + } + + // optional int32 ret = 2; + case 2: { + if (tag == 16) { + parse_ret: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &ret_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_master_nodeid; + break; + } + + // optional uint64 master_nodeid = 3; + case 3: { + if (tag == 24) { + parse_master_nodeid: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &master_nodeid_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxkv.KVResponse) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxkv.KVResponse) + return false; +#undef DO_ +} + +void KVResponse::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxkv.KVResponse) + // optional .phxkv.KVData data = 1; + if (this->has_data()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, *this->data_, output); + } + + // optional int32 ret = 2; + if (this->ret() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->ret(), output); + } + + // optional uint64 master_nodeid = 3; + if (this->master_nodeid() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->master_nodeid(), output); + } + + // @@protoc_insertion_point(serialize_end:phxkv.KVResponse) +} + +::google::protobuf::uint8* KVResponse::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxkv.KVResponse) + // optional .phxkv.KVData data = 1; + if (this->has_data()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, *this->data_, target); + } + + // optional int32 ret = 2; + if (this->ret() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->ret(), target); + } + + // optional uint64 master_nodeid = 3; + if (this->master_nodeid() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->master_nodeid(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:phxkv.KVResponse) + return target; +} + +int KVResponse::ByteSize() const { + int total_size = 0; + + // optional .phxkv.KVData data = 1; + if (this->has_data()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->data_); + } + + // optional int32 ret = 2; + if (this->ret() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->ret()); + } + + // optional uint64 master_nodeid = 3; + if (this->master_nodeid() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->master_nodeid()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void KVResponse::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const KVResponse* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void KVResponse::MergeFrom(const KVResponse& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.has_data()) { + mutable_data()->::phxkv::KVData::MergeFrom(from.data()); + } + if (from.ret() != 0) { + set_ret(from.ret()); + } + if (from.master_nodeid() != 0) { + set_master_nodeid(from.master_nodeid()); + } +} + +void KVResponse::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void KVResponse::CopyFrom(const KVResponse& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool KVResponse::IsInitialized() const { + + return true; +} + +void KVResponse::Swap(KVResponse* other) { + if (other == this) return; + InternalSwap(other); +} +void KVResponse::InternalSwap(KVResponse* other) { + std::swap(data_, other->data_); + std::swap(ret_, other->ret_); + std::swap(master_nodeid_, other->master_nodeid_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata KVResponse::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = KVResponse_descriptor_; + metadata.reflection = KVResponse_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// KVResponse + +// optional .phxkv.KVData data = 1; +bool KVResponse::has_data() const { + return !_is_default_instance_ && data_ != NULL; +} +void KVResponse::clear_data() { + if (GetArenaNoVirtual() == NULL && data_ != NULL) delete data_; + data_ = NULL; +} +const ::phxkv::KVData& KVResponse::data() const { + // @@protoc_insertion_point(field_get:phxkv.KVResponse.data) + return data_ != NULL ? *data_ : *default_instance_->data_; +} +::phxkv::KVData* KVResponse::mutable_data() { + + if (data_ == NULL) { + data_ = new ::phxkv::KVData; + } + // @@protoc_insertion_point(field_mutable:phxkv.KVResponse.data) + return data_; +} +::phxkv::KVData* KVResponse::release_data() { + + ::phxkv::KVData* temp = data_; + data_ = NULL; + return temp; +} +void KVResponse::set_allocated_data(::phxkv::KVData* data) { + delete data_; + data_ = data; + if (data) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:phxkv.KVResponse.data) +} + +// optional int32 ret = 2; +void KVResponse::clear_ret() { + ret_ = 0; +} + ::google::protobuf::int32 KVResponse::ret() const { + // @@protoc_insertion_point(field_get:phxkv.KVResponse.ret) + return ret_; +} + void KVResponse::set_ret(::google::protobuf::int32 value) { + + ret_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVResponse.ret) +} + +// optional uint64 master_nodeid = 3; +void KVResponse::clear_master_nodeid() { + master_nodeid_ = GOOGLE_ULONGLONG(0); +} + ::google::protobuf::uint64 KVResponse::master_nodeid() const { + // @@protoc_insertion_point(field_get:phxkv.KVResponse.master_nodeid) + return master_nodeid_; +} + void KVResponse::set_master_nodeid(::google::protobuf::uint64 value) { + + master_nodeid_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVResponse.master_nodeid) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace phxkv + +// @@protoc_insertion_point(global_scope) diff --git a/sample/phxkv/phxkv.pb.h b/sample/phxkv/phxkv.pb.h new file mode 100644 index 000000000..a3992bcf8 --- /dev/null +++ b/sample/phxkv/phxkv.pb.h @@ -0,0 +1,643 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: phxkv.proto + +#ifndef PROTOBUF_phxkv_2eproto__INCLUDED +#define PROTOBUF_phxkv_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace phxkv { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_phxkv_2eproto(); +void protobuf_AssignDesc_phxkv_2eproto(); +void protobuf_ShutdownFile_phxkv_2eproto(); + +class KVData; +class KVOperator; +class KVResponse; + +// =================================================================== + +class KVOperator : public ::google::protobuf::Message { + public: + KVOperator(); + virtual ~KVOperator(); + + KVOperator(const KVOperator& from); + + inline KVOperator& operator=(const KVOperator& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const KVOperator& default_instance(); + + void Swap(KVOperator* other); + + // implements Message ---------------------------------------------- + + inline KVOperator* New() const { return New(NULL); } + + KVOperator* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const KVOperator& from); + void MergeFrom(const KVOperator& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(KVOperator* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string key = 1; + void clear_key(); + static const int kKeyFieldNumber = 1; + const ::std::string& key() const; + void set_key(const ::std::string& value); + void set_key(const char* value); + void set_key(const char* value, size_t size); + ::std::string* mutable_key(); + ::std::string* release_key(); + void set_allocated_key(::std::string* key); + + // optional bytes value = 2; + void clear_value(); + static const int kValueFieldNumber = 2; + const ::std::string& value() const; + void set_value(const ::std::string& value); + void set_value(const char* value); + void set_value(const void* value, size_t size); + ::std::string* mutable_value(); + ::std::string* release_value(); + void set_allocated_value(::std::string* value); + + // optional uint64 version = 3; + void clear_version(); + static const int kVersionFieldNumber = 3; + ::google::protobuf::uint64 version() const; + void set_version(::google::protobuf::uint64 value); + + // optional uint32 operator = 4; + void clear_operator_(); + static const int kOperatorFieldNumber = 4; + ::google::protobuf::uint32 operator_() const; + void set_operator_(::google::protobuf::uint32 value); + + // optional uint32 sid = 5; + void clear_sid(); + static const int kSidFieldNumber = 5; + ::google::protobuf::uint32 sid() const; + void set_sid(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:phxkv.KVOperator) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr key_; + ::google::protobuf::internal::ArenaStringPtr value_; + ::google::protobuf::uint64 version_; + ::google::protobuf::uint32 operator__; + ::google::protobuf::uint32 sid_; + mutable int _cached_size_; + friend void protobuf_AddDesc_phxkv_2eproto(); + friend void protobuf_AssignDesc_phxkv_2eproto(); + friend void protobuf_ShutdownFile_phxkv_2eproto(); + + void InitAsDefaultInstance(); + static KVOperator* default_instance_; +}; +// ------------------------------------------------------------------- + +class KVData : public ::google::protobuf::Message { + public: + KVData(); + virtual ~KVData(); + + KVData(const KVData& from); + + inline KVData& operator=(const KVData& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const KVData& default_instance(); + + void Swap(KVData* other); + + // implements Message ---------------------------------------------- + + inline KVData* New() const { return New(NULL); } + + KVData* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const KVData& from); + void MergeFrom(const KVData& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(KVData* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bytes value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + const ::std::string& value() const; + void set_value(const ::std::string& value); + void set_value(const char* value); + void set_value(const void* value, size_t size); + ::std::string* mutable_value(); + ::std::string* release_value(); + void set_allocated_value(::std::string* value); + + // optional uint64 version = 2; + void clear_version(); + static const int kVersionFieldNumber = 2; + ::google::protobuf::uint64 version() const; + void set_version(::google::protobuf::uint64 value); + + // optional bool isdeleted = 3; + void clear_isdeleted(); + static const int kIsdeletedFieldNumber = 3; + bool isdeleted() const; + void set_isdeleted(bool value); + + // @@protoc_insertion_point(class_scope:phxkv.KVData) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr value_; + ::google::protobuf::uint64 version_; + bool isdeleted_; + mutable int _cached_size_; + friend void protobuf_AddDesc_phxkv_2eproto(); + friend void protobuf_AssignDesc_phxkv_2eproto(); + friend void protobuf_ShutdownFile_phxkv_2eproto(); + + void InitAsDefaultInstance(); + static KVData* default_instance_; +}; +// ------------------------------------------------------------------- + +class KVResponse : public ::google::protobuf::Message { + public: + KVResponse(); + virtual ~KVResponse(); + + KVResponse(const KVResponse& from); + + inline KVResponse& operator=(const KVResponse& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const KVResponse& default_instance(); + + void Swap(KVResponse* other); + + // implements Message ---------------------------------------------- + + inline KVResponse* New() const { return New(NULL); } + + KVResponse* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const KVResponse& from); + void MergeFrom(const KVResponse& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(KVResponse* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .phxkv.KVData data = 1; + bool has_data() const; + void clear_data(); + static const int kDataFieldNumber = 1; + const ::phxkv::KVData& data() const; + ::phxkv::KVData* mutable_data(); + ::phxkv::KVData* release_data(); + void set_allocated_data(::phxkv::KVData* data); + + // optional int32 ret = 2; + void clear_ret(); + static const int kRetFieldNumber = 2; + ::google::protobuf::int32 ret() const; + void set_ret(::google::protobuf::int32 value); + + // optional uint64 master_nodeid = 3; + void clear_master_nodeid(); + static const int kMasterNodeidFieldNumber = 3; + ::google::protobuf::uint64 master_nodeid() const; + void set_master_nodeid(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:phxkv.KVResponse) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::phxkv::KVData* data_; + ::google::protobuf::uint64 master_nodeid_; + ::google::protobuf::int32 ret_; + mutable int _cached_size_; + friend void protobuf_AddDesc_phxkv_2eproto(); + friend void protobuf_AssignDesc_phxkv_2eproto(); + friend void protobuf_ShutdownFile_phxkv_2eproto(); + + void InitAsDefaultInstance(); + static KVResponse* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// KVOperator + +// optional string key = 1; +inline void KVOperator::clear_key() { + key_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& KVOperator::key() const { + // @@protoc_insertion_point(field_get:phxkv.KVOperator.key) + return key_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void KVOperator::set_key(const ::std::string& value) { + + key_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxkv.KVOperator.key) +} +inline void KVOperator::set_key(const char* value) { + + key_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxkv.KVOperator.key) +} +inline void KVOperator::set_key(const char* value, size_t size) { + + key_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxkv.KVOperator.key) +} +inline ::std::string* KVOperator::mutable_key() { + + // @@protoc_insertion_point(field_mutable:phxkv.KVOperator.key) + return key_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* KVOperator::release_key() { + + return key_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void KVOperator::set_allocated_key(::std::string* key) { + if (key != NULL) { + + } else { + + } + key_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), key); + // @@protoc_insertion_point(field_set_allocated:phxkv.KVOperator.key) +} + +// optional bytes value = 2; +inline void KVOperator::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& KVOperator::value() const { + // @@protoc_insertion_point(field_get:phxkv.KVOperator.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void KVOperator::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxkv.KVOperator.value) +} +inline void KVOperator::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxkv.KVOperator.value) +} +inline void KVOperator::set_value(const void* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxkv.KVOperator.value) +} +inline ::std::string* KVOperator::mutable_value() { + + // @@protoc_insertion_point(field_mutable:phxkv.KVOperator.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* KVOperator::release_value() { + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void KVOperator::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:phxkv.KVOperator.value) +} + +// optional uint64 version = 3; +inline void KVOperator::clear_version() { + version_ = GOOGLE_ULONGLONG(0); +} +inline ::google::protobuf::uint64 KVOperator::version() const { + // @@protoc_insertion_point(field_get:phxkv.KVOperator.version) + return version_; +} +inline void KVOperator::set_version(::google::protobuf::uint64 value) { + + version_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVOperator.version) +} + +// optional uint32 operator = 4; +inline void KVOperator::clear_operator_() { + operator__ = 0u; +} +inline ::google::protobuf::uint32 KVOperator::operator_() const { + // @@protoc_insertion_point(field_get:phxkv.KVOperator.operator) + return operator__; +} +inline void KVOperator::set_operator_(::google::protobuf::uint32 value) { + + operator__ = value; + // @@protoc_insertion_point(field_set:phxkv.KVOperator.operator) +} + +// optional uint32 sid = 5; +inline void KVOperator::clear_sid() { + sid_ = 0u; +} +inline ::google::protobuf::uint32 KVOperator::sid() const { + // @@protoc_insertion_point(field_get:phxkv.KVOperator.sid) + return sid_; +} +inline void KVOperator::set_sid(::google::protobuf::uint32 value) { + + sid_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVOperator.sid) +} + +// ------------------------------------------------------------------- + +// KVData + +// optional bytes value = 1; +inline void KVData::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& KVData::value() const { + // @@protoc_insertion_point(field_get:phxkv.KVData.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void KVData::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxkv.KVData.value) +} +inline void KVData::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxkv.KVData.value) +} +inline void KVData::set_value(const void* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxkv.KVData.value) +} +inline ::std::string* KVData::mutable_value() { + + // @@protoc_insertion_point(field_mutable:phxkv.KVData.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* KVData::release_value() { + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void KVData::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:phxkv.KVData.value) +} + +// optional uint64 version = 2; +inline void KVData::clear_version() { + version_ = GOOGLE_ULONGLONG(0); +} +inline ::google::protobuf::uint64 KVData::version() const { + // @@protoc_insertion_point(field_get:phxkv.KVData.version) + return version_; +} +inline void KVData::set_version(::google::protobuf::uint64 value) { + + version_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVData.version) +} + +// optional bool isdeleted = 3; +inline void KVData::clear_isdeleted() { + isdeleted_ = false; +} +inline bool KVData::isdeleted() const { + // @@protoc_insertion_point(field_get:phxkv.KVData.isdeleted) + return isdeleted_; +} +inline void KVData::set_isdeleted(bool value) { + + isdeleted_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVData.isdeleted) +} + +// ------------------------------------------------------------------- + +// KVResponse + +// optional .phxkv.KVData data = 1; +inline bool KVResponse::has_data() const { + return !_is_default_instance_ && data_ != NULL; +} +inline void KVResponse::clear_data() { + if (GetArenaNoVirtual() == NULL && data_ != NULL) delete data_; + data_ = NULL; +} +inline const ::phxkv::KVData& KVResponse::data() const { + // @@protoc_insertion_point(field_get:phxkv.KVResponse.data) + return data_ != NULL ? *data_ : *default_instance_->data_; +} +inline ::phxkv::KVData* KVResponse::mutable_data() { + + if (data_ == NULL) { + data_ = new ::phxkv::KVData; + } + // @@protoc_insertion_point(field_mutable:phxkv.KVResponse.data) + return data_; +} +inline ::phxkv::KVData* KVResponse::release_data() { + + ::phxkv::KVData* temp = data_; + data_ = NULL; + return temp; +} +inline void KVResponse::set_allocated_data(::phxkv::KVData* data) { + delete data_; + data_ = data; + if (data) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:phxkv.KVResponse.data) +} + +// optional int32 ret = 2; +inline void KVResponse::clear_ret() { + ret_ = 0; +} +inline ::google::protobuf::int32 KVResponse::ret() const { + // @@protoc_insertion_point(field_get:phxkv.KVResponse.ret) + return ret_; +} +inline void KVResponse::set_ret(::google::protobuf::int32 value) { + + ret_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVResponse.ret) +} + +// optional uint64 master_nodeid = 3; +inline void KVResponse::clear_master_nodeid() { + master_nodeid_ = GOOGLE_ULONGLONG(0); +} +inline ::google::protobuf::uint64 KVResponse::master_nodeid() const { + // @@protoc_insertion_point(field_get:phxkv.KVResponse.master_nodeid) + return master_nodeid_; +} +inline void KVResponse::set_master_nodeid(::google::protobuf::uint64 value) { + + master_nodeid_ = value; + // @@protoc_insertion_point(field_set:phxkv.KVResponse.master_nodeid) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace phxkv + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_phxkv_2eproto__INCLUDED diff --git a/sample/phxkv/phxkv.proto b/sample/phxkv/phxkv.proto new file mode 100644 index 000000000..601795643 --- /dev/null +++ b/sample/phxkv/phxkv.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; + +package phxkv; + +service PhxKVServer { + rpc Put(KVOperator) returns (KVResponse) { } + rpc GetLocal(KVOperator) returns (KVResponse) { } + rpc GetGlobal(KVOperator) returns (KVResponse) { } + rpc Delete(KVOperator) returns (KVResponse) { } +} + +message KVOperator +{ + string key = 1; + bytes value = 2; + uint64 version = 3; + uint32 operator = 4; + uint32 sid = 5; +}; + +message KVData +{ + bytes value = 1; + uint64 version = 2; + bool isdeleted = 3; +}; + +message KVResponse +{ + KVData data = 1; + int32 ret = 2; + uint64 master_nodeid = 3; +}; diff --git a/sample/phxkv/prepare_dir.sh b/sample/phxkv/prepare_dir.sh new file mode 100644 index 000000000..3a7537af6 --- /dev/null +++ b/sample/phxkv/prepare_dir.sh @@ -0,0 +1,13 @@ +#create kvdb path and paxoslog path +mkdir storage +cd storage +mkdir kvdb_0 +mkdir paxoslog_0 +mkdir kvdb_1 +mkdir paxoslog_1 +mkdir kvdb_2 +mkdir paxoslog_2 +cd .. + +#create glog path +mkdir log diff --git a/sample/phxkv/run_server_sample.sh b/sample/phxkv/run_server_sample.sh new file mode 100644 index 000000000..2784f1bf3 --- /dev/null +++ b/sample/phxkv/run_server_sample.sh @@ -0,0 +1,4 @@ +#sample +#./phxkv_grpcserver 127.0.0.1:21111 127.0.0.1:11111 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113 ./storage/kvdb_0 ./storage/paxoslog_0 +#./phxkv_grpcserver 127.0.0.1:21112 127.0.0.1:11112 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113 ./storage/kvdb_1 ./storage/paxoslog_1 +#./phxkv_grpcserver 127.0.0.1:21113 127.0.0.1:11113 127.0.0.1:11111,127.0.0.1:11112,127.0.0.1:11113 ./storage/kvdb_2 ./storage/paxoslog_2 diff --git a/sample/phxkv/utils.cpp b/sample/phxkv/utils.cpp new file mode 100644 index 000000000..58d029e75 --- /dev/null +++ b/sample/phxkv/utils.cpp @@ -0,0 +1,63 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "utils.h" + +namespace phxkv +{ + +Mutex::Mutex() { + if (pthread_mutex_init(&_pm, 0)) { + throw SyncException(errno, "pthread_mutex_init error"); + } +} + +Mutex::~Mutex() { + pthread_mutex_destroy(&_pm); +} + +void Mutex::lock() { + int ret = pthread_mutex_lock(&_pm); + if (ret) { + throw SyncException(ret, "pthread_mutex_lock error"); + } +} + +bool Mutex::tryLock() { + int ret = pthread_mutex_trylock(&_pm); + if (ret) { + if (ret == EBUSY) { + return false; + } + throw SyncException(ret, "pthread_mutex_trylock error"); + } + return true; +} + +void Mutex::unlock() { + int ret = pthread_mutex_unlock(&_pm); + if (ret) { + throw SyncException(ret, "pthread_mutex_unlock error"); + } +} + +} + diff --git a/sample/phxkv/utils.h b/sample/phxkv/utils.h new file mode 100644 index 000000000..a53eecbf4 --- /dev/null +++ b/sample/phxkv/utils.h @@ -0,0 +1,130 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace phxkv +{ + +class SysCallException : public std::exception { +public: + SysCallException(int errCode, const std::string& errMsg, bool detail = true) : _errCode(errCode), _errMsg(errMsg) { + if (detail) { + _errMsg.append(", ").append(::strerror(errCode)); + } + } + + virtual ~SysCallException() throw () {} + + int getErrorCode() const throw () { + return _errCode; + } + + const char* what() const throw () { + return _errMsg.c_str(); + } + +protected: + int _errCode; + std::string _errMsg; +}; + + +class SyncException : public SysCallException { +public: + SyncException(int errCode, const std::string& errMsg, bool detail = true) + : SysCallException(errCode, errMsg, detail) {} + + virtual ~SyncException() throw () {} +}; + +class Noncopyable { +protected: + Noncopyable() {} + ~Noncopyable() {} +private: + Noncopyable(const Noncopyable&); + const Noncopyable& operator=(const Noncopyable&); +}; + +class Mutex : public Noncopyable { +public: + Mutex(); + + ~Mutex(); + + void lock(); + + bool tryLock(); + + void unlock(); + +private: + + friend class Condition; + + pthread_mutex_t _pm; +}; + +template +class ScopedLock : public Noncopyable { +public: + ScopedLock(Lock& lock, bool locked = false) : _locked(locked), _lock(lock) { + this->lock(); + } + + ~ScopedLock() { + this->unlock(); + } + + void lock() { + if (!_locked) { + _lock.lock(); + _locked = true; + } + } + + void unlock() { + if (_locked) { + _lock.unlock(); + _locked = false; + } + } + +private: + bool _locked; + Lock& _lock; +}; + + +} diff --git a/src/algorithm/Makefile.define b/src/algorithm/Makefile.define new file mode 100644 index 000000000..973eed7c5 --- /dev/null +++ b/src/algorithm/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libalgorithm.a + +ALGORITHM_OBJ=base.o proposer.o acceptor.o learner.o learner_sender.o instance.o ioloop.o commitctx.o committer.o checkpoint_sender.o checkpoint_receiver.o msg_counter.o + +ALGORITHM_LIB=algorithm src/comm:comm src/logstorage:logstorage src/sm-base:smbase include:include src/checkpoint:checkpoint src/config:config + +ALGORITHM_SYS_LIB= + +ALGORITHM_INCS=$(SRC_BASE_PATH)/src/algorithm + +ALGORITHM_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/algorithm/acceptor.cpp b/src/algorithm/acceptor.cpp new file mode 100644 index 000000000..df63117f1 --- /dev/null +++ b/src/algorithm/acceptor.cpp @@ -0,0 +1,336 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "acceptor.h" +#include "paxos_log.h" +#include "crc32.h" + +namespace phxpaxos +{ + +AcceptorState :: AcceptorState(const Config * poConfig, const LogStorage * poLogStorage) : + m_oPaxosLog(poLogStorage) +{ + m_poConfig = (Config *)poConfig; + Init(); +} + +AcceptorState :: ~AcceptorState() +{ +} + +void AcceptorState :: Init() +{ + m_oAcceptedBallot.reset(); + + m_sAcceptedValue = ""; + + m_iChecksum = 0; +} + +const BallotNumber & AcceptorState :: GetPromiseBallot() const +{ + return m_oPromiseBallot; +} + +void AcceptorState :: SetPromiseBallot(const BallotNumber & oPromiseBallot) +{ + m_oPromiseBallot = oPromiseBallot; +} + +const BallotNumber & AcceptorState :: GetAcceptedBallot() const +{ + return m_oAcceptedBallot; +} + +void AcceptorState :: SetAcceptedBallot(const BallotNumber & oAcceptedBallot) +{ + m_oAcceptedBallot = oAcceptedBallot; +} + +const std::string & AcceptorState :: GetAcceptedValue() +{ + return m_sAcceptedValue; +} + +void AcceptorState :: SetAcceptedValue(const std::string & sAcceptedValue) +{ + m_sAcceptedValue = sAcceptedValue; +} + +const uint32_t AcceptorState :: GetChecksum() const +{ + return m_iChecksum; +} + +int AcceptorState :: Persist(const uint64_t llInstanceID, const uint32_t iLastChecksum) +{ + if (llInstanceID > 0 && iLastChecksum == 0) + { + m_iChecksum = 0; + } + else if (m_sAcceptedValue.size() > 0) + { + m_iChecksum = crc32(iLastChecksum, (const uint8_t *)m_sAcceptedValue.data(), m_sAcceptedValue.size(), CRC32SKIP); + } + + AcceptorStateData oState; + oState.set_instanceid(llInstanceID); + oState.set_promiseid(m_oPromiseBallot.m_llProposalID); + oState.set_promisenodeid(m_oPromiseBallot.m_llNodeID); + oState.set_acceptedid(m_oAcceptedBallot.m_llProposalID); + oState.set_acceptednodeid(m_oAcceptedBallot.m_llNodeID); + oState.set_acceptedvalue(m_sAcceptedValue); + oState.set_checksum(m_iChecksum); + + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + + int ret = m_oPaxosLog.WriteState(oWriteOptions, m_poConfig->GetMyGroupIdx(), llInstanceID, oState); + if (ret != 0) + { + return ret; + } + + PLGImp("GroupIdx %d InstanceID %lu PromiseID %lu PromiseNodeID %lu " + "AccectpedID %lu AcceptedNodeID %lu ValueLen %zu Checksum %u", + m_poConfig->GetMyGroupIdx(), llInstanceID, m_oPromiseBallot.m_llProposalID, + m_oPromiseBallot.m_llNodeID, m_oAcceptedBallot.m_llProposalID, + m_oAcceptedBallot.m_llNodeID, m_sAcceptedValue.size(), m_iChecksum); + + return 0; +} + +int AcceptorState :: Load(uint64_t & llInstanceID) +{ + int ret = m_oPaxosLog.GetMaxInstanceIDFromLog(m_poConfig->GetMyGroupIdx(), llInstanceID); + if (ret != 0 && ret != 1) + { + PLGErr("Load max instance id fail, ret %d", ret); + return ret; + } + + if (ret == 1) + { + PLGErr("empty database"); + llInstanceID = 0; + return 0; + } + + AcceptorStateData oState; + ret = m_oPaxosLog.ReadState(m_poConfig->GetMyGroupIdx(), llInstanceID, oState); + if (ret != 0) + { + return ret; + } + + m_oPromiseBallot.m_llProposalID = oState.promiseid(); + m_oPromiseBallot.m_llNodeID = oState.promisenodeid(); + m_oAcceptedBallot.m_llProposalID = oState.acceptedid(); + m_oAcceptedBallot.m_llNodeID = oState.acceptednodeid(); + m_sAcceptedValue = oState.acceptedvalue(); + m_iChecksum = oState.checksum(); + + PLGImp("GroupIdx %d InstanceID %lu PromiseID %lu PromiseNodeID %lu" + " AccectpedID %lu AcceptedNodeID %lu ValueLen %zu Checksum %u", + m_poConfig->GetMyGroupIdx(), llInstanceID, m_oPromiseBallot.m_llProposalID, + m_oPromiseBallot.m_llNodeID, m_oAcceptedBallot.m_llProposalID, + m_oAcceptedBallot.m_llNodeID, m_sAcceptedValue.size(), m_iChecksum); + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////// + +Acceptor :: Acceptor( + const Config * poConfig, + const MsgTransport * poMsgTransport, + const Instance * poInstance, + const LogStorage * poLogStorage) + : Base(poConfig, poMsgTransport, poInstance), m_oAcceptorState(poConfig, poLogStorage) +{ +} + +Acceptor :: ~Acceptor() +{ +} + +int Acceptor :: Init() +{ + uint64_t llInstanceID = 0; + int ret = m_oAcceptorState.Load(llInstanceID); + if (ret != 0) + { + NLErr("Load State fail, ret %d", ret); + return ret; + } + + if (llInstanceID == 0) + { + PLGImp("Empty database"); + } + + SetInstanceID(llInstanceID); + + PLGImp("OK"); + + return 0; +} + +void Acceptor :: InitForNewPaxosInstance() +{ + m_oAcceptorState.Init(); +} + +AcceptorState * Acceptor :: GetAcceptorState() +{ + return &m_oAcceptorState; +} + +int Acceptor :: OnPrepare(const PaxosMsg & oPaxosMsg) +{ + PLGHead("START Msg.InstanceID %lu Msg.from_nodeid %lu Msg.ProposalID %lu", + oPaxosMsg.instanceid(), oPaxosMsg.nodeid(), oPaxosMsg.proposalid()); + + BP->GetAcceptorBP()->OnPrepare(); + + PaxosMsg oReplyPaxosMsg; + oReplyPaxosMsg.set_instanceid(GetInstanceID()); + oReplyPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oReplyPaxosMsg.set_proposalid(oPaxosMsg.proposalid()); + oReplyPaxosMsg.set_msgtype(MsgType_PaxosPrepareReply); + + BallotNumber oBallot(oPaxosMsg.proposalid(), oPaxosMsg.nodeid()); + + if (oBallot >= m_oAcceptorState.GetPromiseBallot()) + { + PLGDebug("[Promise] State.PromiseID %lu State.PromiseNodeID %lu " + "State.PreAcceptedID %lu State.PreAcceptedNodeID %lu", + m_oAcceptorState.GetPromiseBallot().m_llProposalID, + m_oAcceptorState.GetPromiseBallot().m_llNodeID, + m_oAcceptorState.GetAcceptedBallot().m_llProposalID, + m_oAcceptorState.GetAcceptedBallot().m_llNodeID); + + oReplyPaxosMsg.set_preacceptid(m_oAcceptorState.GetAcceptedBallot().m_llProposalID); + oReplyPaxosMsg.set_preacceptnodeid(m_oAcceptorState.GetAcceptedBallot().m_llNodeID); + + if (m_oAcceptorState.GetAcceptedBallot().m_llProposalID > 0) + { + oReplyPaxosMsg.set_value(m_oAcceptorState.GetAcceptedValue()); + } + + m_oAcceptorState.SetPromiseBallot(oBallot); + + int ret = m_oAcceptorState.Persist(GetInstanceID(), GetLastChecksum()); + if (ret != 0) + { + BP->GetAcceptorBP()->OnPreparePersistFail(); + PLGErr("Persist fail, Now.InstanceID %lu ret %d", + GetInstanceID(), ret); + + return -1; + } + + BP->GetAcceptorBP()->OnPreparePass(); + } + else + { + BP->GetAcceptorBP()->OnPrepareReject(); + + PLGDebug("[Reject] State.PromiseID %lu State.PromiseNodeID %lu", + m_oAcceptorState.GetPromiseBallot().m_llProposalID, + m_oAcceptorState.GetPromiseBallot().m_llNodeID); + + oReplyPaxosMsg.set_rejectbypromiseid(m_oAcceptorState.GetPromiseBallot().m_llProposalID); + } + + nodeid_t iReplyNodeID = oPaxosMsg.nodeid(); + + PLGHead("END Now.InstanceID %lu ReplyNodeID %lu", + GetInstanceID(), oPaxosMsg.nodeid());; + + SendMessage(iReplyNodeID, oReplyPaxosMsg); + + return 0; +} + +void Acceptor :: OnAccept(const PaxosMsg & oPaxosMsg) +{ + PLGHead("START Msg.InstanceID %lu Msg.from_nodeid %lu Msg.ProposalID %lu Msg.ValueLen %zu", + oPaxosMsg.instanceid(), oPaxosMsg.nodeid(), oPaxosMsg.proposalid(), oPaxosMsg.value().size()); + + BP->GetAcceptorBP()->OnAccept(); + + PaxosMsg oReplyPaxosMsg; + oReplyPaxosMsg.set_instanceid(GetInstanceID()); + oReplyPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oReplyPaxosMsg.set_proposalid(oPaxosMsg.proposalid()); + oReplyPaxosMsg.set_msgtype(MsgType_PaxosAcceptReply); + + BallotNumber oBallot(oPaxosMsg.proposalid(), oPaxosMsg.nodeid()); + + if (oBallot >= m_oAcceptorState.GetPromiseBallot()) + { + PLGDebug("[Promise] State.PromiseID %lu State.PromiseNodeID %lu " + "State.PreAcceptedID %lu State.PreAcceptedNodeID %lu", + m_oAcceptorState.GetPromiseBallot().m_llProposalID, + m_oAcceptorState.GetPromiseBallot().m_llNodeID, + m_oAcceptorState.GetAcceptedBallot().m_llProposalID, + m_oAcceptorState.GetAcceptedBallot().m_llNodeID); + + m_oAcceptorState.SetPromiseBallot(oBallot); + m_oAcceptorState.SetAcceptedBallot(oBallot); + m_oAcceptorState.SetAcceptedValue(oPaxosMsg.value()); + + int ret = m_oAcceptorState.Persist(GetInstanceID(), GetLastChecksum()); + if (ret != 0) + { + BP->GetAcceptorBP()->OnAcceptPersistFail(); + + PLGErr("Persist fail, Now.InstanceID %lu ret %d", + GetInstanceID(), ret); + + return; + } + + BP->GetAcceptorBP()->OnAcceptPass(); + } + else + { + BP->GetAcceptorBP()->OnAcceptReject(); + + PLGDebug("[Reject] State.PromiseID %lu State.PromiseNodeID %lu", + m_oAcceptorState.GetPromiseBallot().m_llProposalID, + m_oAcceptorState.GetPromiseBallot().m_llNodeID); + + oReplyPaxosMsg.set_rejectbypromiseid(m_oAcceptorState.GetPromiseBallot().m_llProposalID); + } + + nodeid_t iReplyNodeID = oPaxosMsg.nodeid(); + + PLGHead("END Now.InstanceID %lu ReplyNodeID %lu", + GetInstanceID(), oPaxosMsg.nodeid()); + + SendMessage(iReplyNodeID, oReplyPaxosMsg); +} + +} + diff --git a/src/algorithm/acceptor.h b/src/algorithm/acceptor.h new file mode 100644 index 000000000..86d703bc5 --- /dev/null +++ b/src/algorithm/acceptor.h @@ -0,0 +1,90 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "base.h" +#include +#include "comm_include.h" +#include "paxos_log.h" + +namespace phxpaxos +{ + +class AcceptorState +{ +public: + AcceptorState(const Config * poConfig, const LogStorage * poLogStorage); + ~AcceptorState(); + + void Init(); + + const BallotNumber & GetPromiseBallot() const; + void SetPromiseBallot(const BallotNumber & oPromiseBallot); + + const BallotNumber & GetAcceptedBallot() const; + void SetAcceptedBallot(const BallotNumber & oAcceptedBallot); + + const std::string & GetAcceptedValue(); + void SetAcceptedValue(const std::string & sAcceptedValue); + + const uint32_t GetChecksum() const; + + int Persist(const uint64_t llInstanceID, const uint32_t iLastChecksum); + int Load(uint64_t & llInstanceID); + +//private: + BallotNumber m_oPromiseBallot; + BallotNumber m_oAcceptedBallot; + std::string m_sAcceptedValue; + uint32_t m_iChecksum; + + Config * m_poConfig; + PaxosLog m_oPaxosLog; +}; + +//////////////////////////////////////////////////////////////// + +class Acceptor : public Base +{ +public: + Acceptor( + const Config * poConfig, + const MsgTransport * poMsgTransport, + const Instance * poInstance, + const LogStorage * poLogStorage); + ~Acceptor(); + + virtual void InitForNewPaxosInstance(); + + int Init(); + + AcceptorState * GetAcceptorState(); + + int OnPrepare(const PaxosMsg & oPaxosMsg); + + void OnAccept(const PaxosMsg & oPaxosMsg); + +//private: + AcceptorState m_oAcceptorState; +}; + +} diff --git a/src/algorithm/base.cpp b/src/algorithm/base.cpp new file mode 100644 index 000000000..6ab398fdf --- /dev/null +++ b/src/algorithm/base.cpp @@ -0,0 +1,300 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "base.h" +#include "msg_transport.h" +#include "instance.h" +#include "crc32.h" + +namespace phxpaxos +{ + +Base :: Base(const Config * poConfig, const MsgTransport * poMsgTransport, const Instance * poInstance) +{ + m_poConfig = (Config *)poConfig; + m_poMsgTransport = (MsgTransport *)poMsgTransport; + m_poInstance = (Instance *)poInstance; + + m_llInstanceID = 0; + + m_bIsTestMode = false; +} + +Base :: ~Base() +{ +} + +uint64_t Base :: GetInstanceID() +{ + return m_llInstanceID; +} + +void Base :: SetInstanceID(const uint64_t llInstanceID) +{ + m_llInstanceID = llInstanceID; +} + +void Base :: NewInstance() +{ + m_llInstanceID++; + InitForNewPaxosInstance(); +} + +const uint32_t Base :: GetLastChecksum() const +{ + return m_poInstance->GetLastChecksum(); +} + +int Base :: PackMsg(const PaxosMsg & oPaxosMsg, std::string & sBuffer) +{ + std::string sBodyBuffer; + bool bSucc = oPaxosMsg.SerializeToString(&sBodyBuffer); + if (!bSucc) + { + PLGErr("PaxosMsg.SerializeToString fail, skip this msg"); + return -1; + } + + int iCmd = MsgCmd_PaxosMsg; + PackBaseMsg(sBodyBuffer, iCmd, sBuffer); + + return 0; +} + +int Base :: PackCheckpointMsg(const CheckpointMsg & oCheckpointMsg, std::string & sBuffer) +{ + std::string sBodyBuffer; + bool bSucc = oCheckpointMsg.SerializeToString(&sBodyBuffer); + if (!bSucc) + { + PLGErr("CheckpointMsg.SerializeToString fail, skip this msg"); + return -1; + } + + int iCmd = MsgCmd_CheckpointMsg; + PackBaseMsg(sBodyBuffer, iCmd, sBuffer); + + return 0; +} + +void Base :: PackBaseMsg(const std::string & sBodyBuffer, const int iCmd, std::string & sBuffer) +{ + char sGroupIdx[GROUPIDXLEN] = {0}; + int iGroupIdx = m_poConfig->GetMyGroupIdx(); + memcpy(sGroupIdx, &iGroupIdx, sizeof(sGroupIdx)); + + Header oHeader; + oHeader.set_gid(m_poConfig->GetGid()); + oHeader.set_rid(0); + oHeader.set_cmdid(iCmd); + oHeader.set_version(1); + + std::string sHeaderBuffer; + bool bSucc = oHeader.SerializeToString(&sHeaderBuffer); + if (!bSucc) + { + PLGErr("Header.SerializeToString fail, skip this msg"); + assert(bSucc == true); + } + + char sHeaderLen[HEADLEN_LEN] = {0}; + uint16_t iHeaderLen = (uint16_t)sHeaderBuffer.size(); + memcpy(sHeaderLen, &iHeaderLen, sizeof(sHeaderLen)); + + sBuffer = string(sGroupIdx, sizeof(sGroupIdx)) + string(sHeaderLen, sizeof(sHeaderLen)) + sHeaderBuffer + sBodyBuffer; + + //check sum + uint32_t iBufferChecksum = crc32(0, (const uint8_t *)sBuffer.data(), sBuffer.size(), NET_CRC32SKIP); + char sBufferChecksum[CHECKSUM_LEN] = {0}; + memcpy(sBufferChecksum, &iBufferChecksum, sizeof(sBufferChecksum)); + + sBuffer += string(sBufferChecksum, sizeof(sBufferChecksum)); +} + +int Base :: UnPackBaseMsg(const std::string & sBuffer, Header & oHeader, size_t & iBodyStartPos, size_t & iBodyLen) +{ + uint16_t iHeaderLen = 0; + memcpy(&iHeaderLen, sBuffer.data() + GROUPIDXLEN, HEADLEN_LEN); + + size_t iHeaderStartPos = GROUPIDXLEN + HEADLEN_LEN; + iBodyStartPos = iHeaderStartPos + iHeaderLen; + + if (iBodyStartPos > sBuffer.size()) + { + BP->GetAlgorithmBaseBP()->UnPackHeaderLenTooLong(); + NLErr("Header headerlen too loog %d", iHeaderLen); + return -1; + } + + bool bSucc = oHeader.ParseFromArray(sBuffer.data() + iHeaderStartPos, iHeaderLen); + if (!bSucc) + { + NLErr("Header.ParseFromArray fail, skip this msg"); + return -1; + } + + NLDebug("buffer_size %zu header len %d cmdid %d gid %lu rid %lu version %d body_startpos %zu", + sBuffer.size(), iHeaderLen, oHeader.cmdid(), oHeader.gid(), oHeader.rid(), oHeader.version(), iBodyStartPos); + + if (oHeader.version() >= 1) + { + if (iBodyStartPos + CHECKSUM_LEN > sBuffer.size()) + { + NLErr("no checksum, body start pos %zu buffersize %zu", iBodyStartPos, sBuffer.size()); + return -1; + } + + iBodyLen = sBuffer.size() - CHECKSUM_LEN - iBodyStartPos; + + uint32_t iBufferChecksum = 0; + memcpy(&iBufferChecksum, sBuffer.data() + sBuffer.size() - CHECKSUM_LEN, CHECKSUM_LEN); + + uint32_t iNewCalBufferChecksum = crc32(0, (const uint8_t *)sBuffer.data(), sBuffer.size() - CHECKSUM_LEN, NET_CRC32SKIP); + if (iNewCalBufferChecksum != iBufferChecksum) + { + BP->GetAlgorithmBaseBP()->UnPackChecksumNotSame(); + NLErr("Data.bring.checksum %u not equal to Data.cal.checksum %u", + iBufferChecksum, iNewCalBufferChecksum); + return -1; + } + + /* + NLDebug("Checksum compare ok, Data.bring.checksum %u, Data.cal.checksum %u", + iBufferChecksum, iNewCalBufferChecksum) + */ + } + else + { + iBodyLen = sBuffer.size() - iBodyStartPos; + } + + return 0; +} + +int Base :: SendMessage(const nodeid_t iSendtoNodeID, const CheckpointMsg & oCheckpointMsg, const int iSendType) +{ + if (iSendtoNodeID == m_poConfig->GetMyNodeID()) + { + return 0; + } + + string sBuffer; + int ret = PackCheckpointMsg(oCheckpointMsg, sBuffer); + if (ret != 0) + { + return ret; + } + + return m_poMsgTransport->SendMessage(iSendtoNodeID, sBuffer, iSendType); +} + +int Base :: SendMessage(const nodeid_t iSendtoNodeID, const PaxosMsg & oPaxosMsg, const int iSendType) +{ + if (m_bIsTestMode) + { + return 0; + } + + BP->GetInstanceBP()->SendMessage(); + + if (iSendtoNodeID == m_poConfig->GetMyNodeID()) + { + m_poInstance->OnReceivePaxosMsg(oPaxosMsg); + return 0; + } + + string sBuffer; + int ret = PackMsg(oPaxosMsg, sBuffer); + if (ret != 0) + { + return ret; + } + + return m_poMsgTransport->SendMessage(iSendtoNodeID, sBuffer, iSendType); +} + +int Base :: BroadcastMessage(const PaxosMsg & oPaxosMsg, const int iRunType, const int iSendType) +{ + if (m_bIsTestMode) + { + return 0; + } + + BP->GetInstanceBP()->BroadcastMessage(); + + if (iRunType == BroadcastMessage_Type_RunSelf_First) + { + if (m_poInstance->OnReceivePaxosMsg(oPaxosMsg) != 0) + { + return -1; + } + } + + string sBuffer; + int ret = PackMsg(oPaxosMsg, sBuffer); + if (ret != 0) + { + return ret; + } + + ret = m_poMsgTransport->BroadcastMessage(sBuffer, iSendType); + + if (iRunType == BroadcastMessage_Type_RunSelf_Final) + { + m_poInstance->OnReceivePaxosMsg(oPaxosMsg); + } + + return ret; +} + +int Base :: BroadcastMessageToFollower(const PaxosMsg & oPaxosMsg, const int iSendType) +{ + string sBuffer; + int ret = PackMsg(oPaxosMsg, sBuffer); + if (ret != 0) + { + return ret; + } + + return m_poMsgTransport->BroadcastMessageFollower(sBuffer, iSendType); +} + +int Base :: BroadcastMessageToTempNode(const PaxosMsg & oPaxosMsg, const int iSendType) +{ + string sBuffer; + int ret = PackMsg(oPaxosMsg, sBuffer); + if (ret != 0) + { + return ret; + } + + return m_poMsgTransport->BroadcastMessageTempNode(sBuffer, iSendType); +} + +/////////////////////////// + +void Base :: SetAsTestMode() +{ + m_bIsTestMode = true; +} + +} + diff --git a/src/algorithm/base.h b/src/algorithm/base.h new file mode 100644 index 000000000..71546b774 --- /dev/null +++ b/src/algorithm/base.h @@ -0,0 +1,168 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "commdef.h" +#include "comm_include.h" +#include "config_include.h" +#include "msg_transport.h" + +namespace phxpaxos +{ + +#define GROUPIDXLEN (sizeof(int)) +#define HEADLEN_LEN (sizeof(uint16_t)) +#define CHECKSUM_LEN (sizeof(uint32_t)) + + +class BallotNumber +{ +public: + BallotNumber() : m_llProposalID(0), m_llNodeID(nullnode) { } + + BallotNumber(const uint64_t llProposalID, const nodeid_t llNodeID) : + m_llProposalID(llProposalID), m_llNodeID(llNodeID) { } + + ~BallotNumber() { } + + bool operator >= (const BallotNumber & other) const + { + if (m_llProposalID == other.m_llProposalID) + { + return m_llNodeID >= other.m_llNodeID; + } + else + { + return m_llProposalID >= other.m_llProposalID; + } + } + + bool operator != (const BallotNumber & other) const + { + return m_llProposalID != other.m_llProposalID + || m_llNodeID != other.m_llNodeID; + } + + bool operator == (const BallotNumber & other) const + { + return m_llProposalID == other.m_llProposalID + && m_llNodeID == other.m_llNodeID; + } + + bool operator > (const BallotNumber & other) const + { + if (m_llProposalID == other.m_llProposalID) + { + return m_llNodeID > other.m_llNodeID; + } + else + { + return m_llProposalID > other.m_llProposalID; + } + } + + const bool isnull() const + { + return m_llProposalID == 0; + } + + void reset() + { + m_llProposalID = 0; + m_llNodeID = 0; + } + + uint64_t m_llProposalID; + nodeid_t m_llNodeID; +}; + +/////////////////////////////////////////////////////////// + +class Instance; + +enum BroadcastMessage_Type +{ + BroadcastMessage_Type_RunSelf_First = 1, + BroadcastMessage_Type_RunSelf_Final = 2, + BroadcastMessage_Type_RunSelf_None = 3, +}; + +class Base +{ +public: + Base(const Config * poConfig, const MsgTransport * poMsgTransport, const Instance * poInstance); + virtual ~Base(); + +public: + uint64_t GetInstanceID(); + + void NewInstance(); + + virtual void InitForNewPaxosInstance() = 0; + + void SetInstanceID(const uint64_t llInstanceID); + + int PackMsg(const PaxosMsg & oPaxosMsg, std::string & sBuffer); + + int PackCheckpointMsg(const CheckpointMsg & oCheckpointMsg, std::string & sBuffer); + +public: + const uint32_t GetLastChecksum() const; + + void PackBaseMsg(const std::string & sBodyBuffer, const int iCmd, std::string & sBuffer); + + static int UnPackBaseMsg(const std::string & sBuffer, Header & oHeader, size_t & iBodyStartPos, size_t & iBodyLen); + + void SetAsTestMode(); + +protected: + virtual int SendMessage(const nodeid_t iSendtoNodeID, const PaxosMsg & oPaxosMsg, const int iSendType = Message_SendType_UDP); + + virtual int BroadcastMessage( + const PaxosMsg & oPaxosMsg, + const int bRunSelfFirst = BroadcastMessage_Type_RunSelf_First, + const int iSendType = Message_SendType_UDP); + + int BroadcastMessageToFollower( + const PaxosMsg & oPaxosMsg, + const int iSendType = Message_SendType_TCP); + + int BroadcastMessageToTempNode( + const PaxosMsg & oPaxosMsg, + const int iSendType = Message_SendType_UDP); + +protected: + int SendMessage(const nodeid_t iSendtoNodeID, const CheckpointMsg & oCheckpointMsg, + const int iSendType = Message_SendType_TCP); + +protected: + Config * m_poConfig; + MsgTransport * m_poMsgTransport; + Instance * m_poInstance; + +private: + uint64_t m_llInstanceID; + + bool m_bIsTestMode; +}; + +} diff --git a/src/algorithm/checkpoint_receiver.cpp b/src/algorithm/checkpoint_receiver.cpp new file mode 100644 index 000000000..4b453ea4e --- /dev/null +++ b/src/algorithm/checkpoint_receiver.cpp @@ -0,0 +1,270 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "checkpoint_receiver.h" +#include "comm_include.h" +#include +#include +#include +#include + +using namespace std; + +namespace phxpaxos +{ + +CheckpointReceiver :: CheckpointReceiver(Config * poConfig, LogStorage * poLogStorage) : + m_poConfig(poConfig), m_poLogStorage(poLogStorage) +{ + Reset(); +} + +CheckpointReceiver :: ~CheckpointReceiver() +{ +} + +void CheckpointReceiver :: Reset() +{ + m_mapHasInitDir.clear(); + + m_iSenderNodeID = nullnode; + m_llUUID = 0; + m_llSequence = 0; +} + +int CheckpointReceiver :: NewReceiver(const nodeid_t iSenderNodeID, const uint64_t llUUID) +{ + int ret = ClearCheckpointTmp(); + if (ret != 0) + { + return ret; + } + + ret = m_poLogStorage->ClearAllLog(m_poConfig->GetMyGroupIdx()); + if (ret != 0) + { + PLGErr("ClearAllLog fail, groupidx %d ret %d", + m_poConfig->GetMyGroupIdx(), ret); + return ret; + } + + m_mapHasInitDir.clear(); + + m_iSenderNodeID = iSenderNodeID; + m_llUUID = llUUID; + m_llSequence = 0; + + return 0; +} + +int CheckpointReceiver :: ClearCheckpointTmp() +{ + string sLogStoragePath = m_poLogStorage->GetLogStorageDirPath(m_poConfig->GetMyGroupIdx()); + + DIR * dir = nullptr; + struct dirent * ptr; + + dir = opendir(sLogStoragePath.c_str()); + if (dir == nullptr) + { + return -1; + } + + int ret = 0; + while ((ptr = readdir(dir)) != nullptr) + { + if (string(ptr->d_name).find("cp_tmp_") != std::string::npos) + { + char sChildPath[1024] = {0}; + snprintf(sChildPath, sizeof(sChildPath), "%s/%s", sLogStoragePath.c_str(), ptr->d_name); + ret = FileUtils::DeleteDir(sChildPath); + + if (ret != 0) + { + break; + } + + PLGHead("rm dir %s done!", sChildPath); + } + } + + closedir(dir); + + return ret; +} + +const bool CheckpointReceiver :: IsReceiverFinish(const nodeid_t iSenderNodeID, + const uint64_t llUUID, const uint64_t llEndSequence) +{ + if (iSenderNodeID == m_iSenderNodeID + && llUUID == m_llUUID + && llEndSequence == m_llSequence + 1) + { + return true; + } + else + { + return false; + } +} + +const std::string CheckpointReceiver :: GetTmpDirPath(const int iSMID) +{ + string sLogStoragePath = m_poLogStorage->GetLogStorageDirPath(m_poConfig->GetMyGroupIdx()); + char sTmpDirPath[512] = {0}; + + snprintf(sTmpDirPath, sizeof(sTmpDirPath), "%s/cp_tmp_%d", sLogStoragePath.c_str(), iSMID); + + return string(sTmpDirPath); +} + +int CheckpointReceiver :: InitFilePath(const std::string & sFilePath, std::string & sFormatFilePath) +{ + PLGHead("START filepath %s", sFilePath.c_str()); + + string sNewFilePath = "/" + sFilePath + "/"; + vector vecDirList; + + std::string sDirName; + for (size_t i = 0; i < sNewFilePath.size(); i++) + { + if (sNewFilePath[i] == '/') + { + if (sDirName.size() > 0) + { + vecDirList.push_back(sDirName); + } + + sDirName = ""; + } + else + { + sDirName += sNewFilePath[i]; + } + } + + sFormatFilePath = "/"; + for (size_t i = 0; i < vecDirList.size(); i++) + { + if (i + 1 == vecDirList.size()) + { + sFormatFilePath += vecDirList[i]; + } + else + { + sFormatFilePath += vecDirList[i] + "/"; + if (m_mapHasInitDir.find(sFormatFilePath) == end(m_mapHasInitDir)) + { + int ret = CreateDir(sFormatFilePath); + if (ret != 0) + { + return ret; + } + + m_mapHasInitDir[sFormatFilePath] = true; + } + } + } + + PLGImp("ok, format filepath %s", sFormatFilePath.c_str()); + + return 0; +} + +int CheckpointReceiver :: CreateDir(const std::string & sDirPath) +{ + if (access(sDirPath.c_str(), F_OK) == -1) + { + if (mkdir(sDirPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) + { + PLGErr("Create dir fail, path %s", sDirPath.c_str()); + return -1; + } + } + + return 0; +} + +int CheckpointReceiver :: ReceiveCheckpoint(const CheckpointMsg & oCheckpointMsg) +{ + if (oCheckpointMsg.nodeid() != m_iSenderNodeID + || oCheckpointMsg.uuid() != m_llUUID) + { + PLGErr("msg not valid, Msg.SenderNodeID %lu Receiver.SenderNodeID %lu Msg.UUID %lu Receiver.UUID %lu", + oCheckpointMsg.nodeid(), m_iSenderNodeID, oCheckpointMsg.uuid(), m_llUUID); + return -2; + } + + if (oCheckpointMsg.sequence() == m_llSequence) + { + PLGErr("msg already receive, skip, Msg.Sequence %lu Receiver.Sequence %lu", + oCheckpointMsg.sequence(), m_llSequence); + return 0; + } + + if (oCheckpointMsg.sequence() != m_llSequence + 1) + { + PLGErr("msg sequence wrong, Msg.Sequence %lu Receiver.Sequence %lu", + oCheckpointMsg.sequence(), m_llSequence); + return -2; + } + + string sFilePath = GetTmpDirPath(oCheckpointMsg.smid()) + "/" + oCheckpointMsg.filepath(); + string sFormatFilePath; + int ret = InitFilePath(sFilePath, sFormatFilePath); + if (ret != 0) + { + return -1; + } + + int iFd = open(sFormatFilePath.c_str(), O_CREAT | O_RDWR | O_APPEND, S_IWRITE | S_IREAD); + if (iFd == -1) + { + PLGErr("open file fail, filepath %s", sFormatFilePath.c_str()); + return -1; + } + + size_t llFileOffset = lseek(iFd, 0, SEEK_END); + if ((uint64_t)llFileOffset != oCheckpointMsg.offset()) + { + PLGErr("file.offset %zu not equal to msg.offset %lu", llFileOffset, oCheckpointMsg.offset()); + close(iFd); + return -2; + } + + size_t iWriteLen = write(iFd, oCheckpointMsg.buffer().data(), oCheckpointMsg.buffer().size()); + if (iWriteLen != oCheckpointMsg.buffer().size()) + { + PLGImp("write fail, writelen %zu buffer size %zu", iWriteLen, oCheckpointMsg.buffer().size()); + close(iFd); + return -1; + } + + m_llSequence++; + close(iFd); + + PLGImp("END ok, writelen %zu", iWriteLen); + + return 0; +} + +} + diff --git a/src/algorithm/checkpoint_receiver.h b/src/algorithm/checkpoint_receiver.h new file mode 100644 index 000000000..005a9f286 --- /dev/null +++ b/src/algorithm/checkpoint_receiver.h @@ -0,0 +1,72 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include "phxpaxos/options.h" +#include "comm_include.h" +#include "config_include.h" + +namespace phxpaxos +{ + +class Config; +class LogStorage; + +class CheckpointReceiver +{ +public: + CheckpointReceiver(Config * poConfig, LogStorage * poLogStorage); + ~CheckpointReceiver(); + + void Reset(); + + int NewReceiver(const nodeid_t iSenderNodeID, const uint64_t llUUID); + + const bool IsReceiverFinish(const nodeid_t iSenderNodeID, const uint64_t llUUID, const uint64_t llEndSequence); + + const std::string GetTmpDirPath(const int iSMID); + + int ReceiveCheckpoint(const CheckpointMsg & oCheckpointMsg); + + int InitFilePath(const std::string & sFilePath, std::string & sFormatFilePath); +private: + + int ClearCheckpointTmp(); + + int CreateDir(const std::string & sDirPath); + +private: + Config * m_poConfig; + LogStorage * m_poLogStorage; + +private: + nodeid_t m_iSenderNodeID; + uint64_t m_llUUID; + uint64_t m_llSequence; + +private: + std::map m_mapHasInitDir; +}; + +} diff --git a/src/algorithm/checkpoint_sender.cpp b/src/algorithm/checkpoint_sender.cpp new file mode 100644 index 000000000..a9bd0f286 --- /dev/null +++ b/src/algorithm/checkpoint_sender.cpp @@ -0,0 +1,384 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "checkpoint_sender.h" +#include "comm_include.h" +#include "learner.h" +#include "sm_base.h" +#include "cp_mgr.h" +#include "crc32.h" +#include +#include +#include +#include "phxpaxos/breakpoint.h" + +namespace phxpaxos +{ + +CheckpointSender :: CheckpointSender( + const nodeid_t iSendNodeID, + Config * poConfig, + Learner * poLearner, + SMFac * poSMFac, + CheckpointMgr * poCheckpointMgr) : + m_iSendNodeID(iSendNodeID), + m_poConfig(poConfig), + m_poLearner(poLearner), + m_poSMFac(poSMFac), + m_poCheckpointMgr(poCheckpointMgr) +{ + m_bIsEnded = false; + m_bIsEnd = false; + m_llUUID = (m_poConfig->GetMyNodeID() ^ m_poLearner->GetInstanceID()) + OtherUtils::FastRand(); + m_llSequence = 0; + + m_llAckSequence = 0; + m_llAbsLastAckTime = 0; +} + +CheckpointSender :: ~CheckpointSender() +{ +} + +void CheckpointSender :: Stop() +{ + if (!m_bIsEnded) + { + m_bIsEnd = true; + join(); + } +} + +void CheckpointSender :: End() +{ + m_bIsEnd = true; +} + +const bool CheckpointSender :: IsEnd() const +{ + return m_bIsEnded; +} + +void CheckpointSender :: run() +{ + m_llAbsLastAckTime = Time::GetTimestampMS(); + + //pause checkpoint replayer + bool bNeedContinue = false; + while (!m_poCheckpointMgr->GetReplayer()->IsPaused()) + { + if (m_bIsEnd) + { + m_bIsEnded = true; + return; + } + + bNeedContinue = true; + + m_poCheckpointMgr->GetReplayer()->Pause(); + PLGDebug("wait replayer paused."); + Time::MsSleep(100); + } + + int ret = LockCheckpoint(); + if (ret == 0) + { + //send + SendCheckpoint(); + + UnLockCheckpoint(); + } + + //continue checkpoint replayer + if (bNeedContinue) + { + m_poCheckpointMgr->GetReplayer()->Continue(); + } + + PLGHead("Checkpoint.Sender [END]"); + m_bIsEnded = true; +} + +int CheckpointSender :: LockCheckpoint() +{ + std::vector vecSMList = m_poSMFac->GetSMList(); + std::vector vecLockSMList; + int ret = 0; + for (auto & poSM : vecSMList) + { + ret = poSM->LockCheckpointState(); + if (ret != 0) + { + break; + } + + vecLockSMList.push_back(poSM); + } + + if (ret != 0) + { + for (auto & poSM : vecLockSMList) + { + poSM->UnLockCheckpointState(); + } + } + + return ret; +} + +void CheckpointSender :: UnLockCheckpoint() +{ + std::vector vecSMList = m_poSMFac->GetSMList(); + for (auto & poSM : vecSMList) + { + poSM->UnLockCheckpointState(); + } +} + +void CheckpointSender :: SendCheckpoint() +{ + int ret = m_poLearner->SendCheckpointBegin( + m_iSendNodeID, m_llUUID, m_llSequence, + m_poSMFac->GetCheckpointInstanceID(m_poConfig->GetMyGroupIdx())); + if (ret != 0) + { + PLGErr("SendCheckpointBegin fail, ret %d", ret); + return; + } + + ret = m_poLearner->SendCheckpointBegin( + m_iSendNodeID, m_llUUID, m_llSequence, + m_poSMFac->GetCheckpointInstanceID(m_poConfig->GetMyGroupIdx())); + if (ret != 0) + { + PLGErr("SendCheckpointBegin fail, ret %d", ret); + return; + } + + BP->GetCheckpointBP()->SendCheckpointBegin(); + + m_llSequence++; + + std::vector vecSMList = m_poSMFac->GetSMList(); + for (auto & poSM : vecSMList) + { + ret = SendCheckpointFofaSM(poSM); + if (ret != 0) + { + return; + } + } + + ret = m_poLearner->SendCheckpointEnd( + m_iSendNodeID, m_llUUID, m_llSequence, + m_poSMFac->GetCheckpointInstanceID(m_poConfig->GetMyGroupIdx())); + if (ret != 0) + { + PLGErr("SendCheckpointEnd fail, sequence %lu ret %d", m_llSequence, ret); + } + + BP->GetCheckpointBP()->SendCheckpointEnd(); +} + +int CheckpointSender :: SendCheckpointFofaSM(StateMachine * poSM) +{ + string sDirPath; + std::vector vecFileList; + + int ret = poSM->GetCheckpointState(m_poConfig->GetMyGroupIdx(), sDirPath, vecFileList); + if (ret != 0) + { + PLGErr("GetCheckpointState fail ret %d, smid %d", ret, poSM->SMID()); + return -1; + } + + if (sDirPath.size() == 0) + { + PLGImp("No Checkpoint, smid %d", poSM->SMID()); + return 0; + } + + if (sDirPath[sDirPath.size() - 1] != '/') + { + sDirPath += '/'; + } + + for (auto & sFilePath : vecFileList) + { + ret = SendFile(poSM, sDirPath, sFilePath); + if (ret != 0) + { + PLGErr("SendFile fail, ret %d smid %d", ret , poSM->SMID()); + return -1; + } + } + + PLGImp("END, send ok, smid %d filelistcount %zu", poSM->SMID(), vecFileList.size()); + return 0; +} + +int CheckpointSender :: SendFile(const StateMachine * poSM, const std::string & sDirPath, const std::string & sFilePath) +{ + PLGHead("START smid %d dirpath %s filepath %s", poSM->SMID(), sDirPath.c_str(), sFilePath.c_str()); + + string sPath = sDirPath + sFilePath; + + if (m_mapAlreadySendedFile.find(sPath) != end(m_mapAlreadySendedFile)) + { + PLGErr("file already send, filepath %s", sPath.c_str()); + return 0; + } + + int iFD = open(sPath.c_str(), O_RDWR, S_IREAD); + + if (iFD == -1) + { + PLGErr("Open file fail, filepath %s", sPath.c_str()); + return -1; + } + + size_t iReadLen = 0; + size_t llOffset = 0; + while (true) + { + iReadLen = read(iFD, m_sTmpBuffer, sizeof(m_sTmpBuffer)); + if (iReadLen == 0) + { + break; + } + + int ret = SendBuffer(poSM->SMID(), poSM->GetCheckpointInstanceID(m_poConfig->GetMyGroupIdx()), + sFilePath, llOffset, string(m_sTmpBuffer, iReadLen)); + if (ret != 0) + { + close(iFD); + return ret; + } + + PLGDebug("Send ok, offset %zu readlen %zu", llOffset, iReadLen); + + if (iReadLen < sizeof(m_sTmpBuffer)) + { + break; + } + + llOffset += iReadLen; + } + + m_mapAlreadySendedFile[sPath] = true; + + close(iFD); + PLGImp("END"); + + return 0; +} + +int CheckpointSender :: SendBuffer(const int iSMID, const uint64_t llCheckpointInstanceID, + const std::string & sFilePath, const uint64_t llOffset, const std::string & sBuffer) +{ + uint32_t iChecksum = crc32(0, (const uint8_t *)sBuffer.data(), sBuffer.size(), CRC32SKIP); + + int ret = 0; + while (true) + { + if (m_bIsEnd) + { + return -1; + } + + if (!CheckAck(m_llSequence)) + { + return -1; + } + + ret = m_poLearner->SendCheckpoint( + m_iSendNodeID, m_llUUID, m_llSequence, llCheckpointInstanceID, + iChecksum, sFilePath, iSMID, llOffset, sBuffer); + + BP->GetCheckpointBP()->SendCheckpointOneBlock(); + + if (ret == 0) + { + m_llSequence++; + break; + } + else + { + PLGErr("SendCheckpoint fail, ret %d need sleep 30s", ret); + Time::MsSleep(30000); + } + } + + return ret; +} + +void CheckpointSender :: Ack(const nodeid_t iSendNodeID, const uint64_t llUUID, const uint64_t llSequence) +{ + if (iSendNodeID != m_iSendNodeID) + { + PLGErr("send nodeid not same, ack.sendnodeid %lu self.sendnodeid %lu", iSendNodeID, m_iSendNodeID); + return; + } + + if (llUUID != m_llUUID) + { + PLGErr("uuid not same, ack.uuid %lu self.uuid %lu", llUUID, m_llUUID); + return; + } + + if (llSequence != m_llAckSequence) + { + PLGErr("ack_sequence not same, ack.ack_sequence %lu self.ack_sequence %lu", llSequence, m_llAckSequence); + return; + } + + m_llAckSequence++; + m_llAbsLastAckTime = Time::GetTimestampMS(); +} + +const bool CheckpointSender :: CheckAck(const uint64_t llSendSequence) +{ + while (llSendSequence > m_llAckSequence + Checkpoint_ACK_LEAD) + { + uint64_t llNowTime = Time::GetTimestampMS(); + uint64_t llPassTime = llNowTime > m_llAbsLastAckTime ? llNowTime - m_llAbsLastAckTime : 0; + + if (m_bIsEnd) + { + return false; + } + + if (llPassTime >= Checkpoint_ACK_TIMEOUT) + { + PLGErr("Ack timeout, last acktime %lu", m_llAbsLastAckTime); + return false; + } + + //PLGErr("Need sleep to slow down send speed, sendsequence %lu acksequence %lu", + //llSendSequence, m_llAckSequence); + Time::MsSleep(20); + } + + return true; +} + +} + diff --git a/src/algorithm/checkpoint_sender.h b/src/algorithm/checkpoint_sender.h new file mode 100644 index 000000000..b810def66 --- /dev/null +++ b/src/algorithm/checkpoint_sender.h @@ -0,0 +1,102 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "utils_include.h" +#include "phxpaxos/options.h" +#include "phxpaxos/sm.h" + +namespace phxpaxos +{ + +class Learner; +class Config; +class SMFac; +class CheckpointMgr; + +#define Checkpoint_ACK_TIMEOUT 120000 +#define Checkpoint_ACK_LEAD 10 + +class CheckpointSender : public Thread +{ +public: + CheckpointSender( + const nodeid_t iSendNodeID, + Config * poConfig, + Learner * poLearner, + SMFac * poSMFac, + CheckpointMgr * poCheckpointMgr); + + ~CheckpointSender(); + + void Stop(); + + void run(); + + void End(); + + const bool IsEnd() const; + + void Ack(const nodeid_t iSendNodeID, const uint64_t llUUID, const uint64_t llSequence); + +private: + void SendCheckpoint(); + + int LockCheckpoint(); + + void UnLockCheckpoint(); + + int SendCheckpointFofaSM(StateMachine * poSM); + + int SendFile(const StateMachine * poSM, const std::string & sDirPath, const std::string & sFilePath); + + int SendBuffer(const int iSMID, const uint64_t llCheckpointInstanceID, const std::string & sFilePath, + const uint64_t llOffset, const std::string & sBuffer); + + const bool CheckAck(const uint64_t llSendSequence); + +private: + nodeid_t m_iSendNodeID; + + Config * m_poConfig; + Learner * m_poLearner; + SMFac * m_poSMFac; + CheckpointMgr * m_poCheckpointMgr; + + bool m_bIsEnd; + bool m_bIsEnded; + +private: + uint64_t m_llUUID; + uint64_t m_llSequence; + +private: + uint64_t m_llAckSequence; + uint64_t m_llAbsLastAckTime; + +private: + char m_sTmpBuffer[1048576]; + + std::map m_mapAlreadySendedFile; +}; + +} diff --git a/src/algorithm/commitctx.cpp b/src/algorithm/commitctx.cpp new file mode 100644 index 000000000..7aaf0a10b --- /dev/null +++ b/src/algorithm/commitctx.cpp @@ -0,0 +1,165 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "commitctx.h" +#include "phxpaxos/sm.h" + +namespace phxpaxos +{ + +CommitCtx :: CommitCtx(Config * poConfig) + : m_poConfig(poConfig) +{ + NewCommit(nullptr, nullptr, nullptr, 0); +} + +CommitCtx :: ~CommitCtx() +{ +} + +void CommitCtx :: NewCommit(std::string * psValue, StateMachine * poSM, SMCtx * poSMCtx, const int iTimeoutMs) +{ + m_oSerialLock.Lock(); + + m_llInstanceID = (uint64_t)-1; + m_iCommitRet = -1; + m_bIsCommitEnd = false; + m_iTimeoutMs = iTimeoutMs; + + m_psValue = psValue; + m_poSM = poSM; + m_poSMCtx = poSMCtx; + + if (psValue != nullptr) + { + PLGHead("OK, valuesize %zu", psValue->size()); + } + + m_oSerialLock.UnLock(); +} + + +const bool CommitCtx :: IsNewCommit() const +{ + return m_llInstanceID == (uint64_t)-1 && m_psValue != nullptr; +} + +const std::string & CommitCtx :: GetCommitValue() +{ + return *m_psValue; +} + +void CommitCtx :: StartCommit(const uint64_t llInstanceID) +{ + m_oSerialLock.Lock(); + m_llInstanceID = llInstanceID; + m_oSerialLock.UnLock(); +} + +bool CommitCtx :: IsMyCommit(const uint64_t llInstanceID, const std::string & sLearnValue, + StateMachine *& poSM, SMCtx *& poSMCtx) +{ + m_oSerialLock.Lock(); + + poSM = nullptr; + bool bIsMyCommit = false; + + if ((!m_bIsCommitEnd) && (m_llInstanceID == llInstanceID)) + { + bIsMyCommit = (sLearnValue == (*m_psValue)); + } + + if (bIsMyCommit) + { + poSM = m_poSM; + poSMCtx = m_poSMCtx; + } + + m_oSerialLock.UnLock(); + + return bIsMyCommit; +} + +void CommitCtx :: SetResultOnlyRet(const int iCommitRet) +{ + return SetResult(iCommitRet, (uint64_t)-1, ""); +} + +void CommitCtx :: SetResult( + const int iCommitRet, + const uint64_t llInstanceID, + const std::string & sLearnValue) +{ + m_oSerialLock.Lock(); + + if (m_bIsCommitEnd || (m_llInstanceID != llInstanceID)) + { + m_oSerialLock.UnLock(); + return; + } + + m_iCommitRet = iCommitRet; + + if (m_iCommitRet == 0) + { + if ((*m_psValue) != sLearnValue) + { + m_iCommitRet = PaxosTryCommitRet_Conflict; + } + } + + m_bIsCommitEnd = true; + m_psValue = nullptr; + + m_oSerialLock.Interupt(); + m_oSerialLock.UnLock(); +} + + +int CommitCtx :: GetResult(uint64_t & llSuccInstanceID) +{ + while (!m_bIsCommitEnd) + { + m_oSerialLock.Wait(); + } + + if (m_iCommitRet == 0) + { + llSuccInstanceID = m_llInstanceID; + PLGImp("commit success, instanceid %lu", llSuccInstanceID); + } + else + { + PLGErr("commit fail, ret %d", m_iCommitRet); + } + + m_oSerialLock.UnLock(); + + return m_iCommitRet; +} + +const int CommitCtx :: GetTimeoutMs() const +{ + return m_iTimeoutMs; +} + +} + diff --git a/src/algorithm/commitctx.h b/src/algorithm/commitctx.h new file mode 100644 index 000000000..322d04ec3 --- /dev/null +++ b/src/algorithm/commitctx.h @@ -0,0 +1,73 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include "comm_include.h" +#include "config_include.h" + +namespace phxpaxos +{ + +class StateMachine; + +class CommitCtx +{ +public: + CommitCtx(Config * poConfig); + ~CommitCtx(); + + void NewCommit(std::string * psValue, StateMachine * poSM, SMCtx * poSMCtx, const int iTimeoutMs); + + const bool IsNewCommit() const; + + const std::string & GetCommitValue(); + + void StartCommit(const uint64_t llInstanceID); + + bool IsMyCommit(const uint64_t llInstanceID, const std::string & sLearnValue, + StateMachine *& poSM, SMCtx *& poSMCtx); + +public: + void SetResult(const int iCommitRet, const uint64_t llInstanceID, const std::string & sLearnValue); + + void SetResultOnlyRet(const int iCommitRet); + + int GetResult(uint64_t & llSuccInstanceID); + +public: + const int GetTimeoutMs() const; + +private: + Config * m_poConfig; + + uint64_t m_llInstanceID; + int m_iCommitRet; + bool m_bIsCommitEnd; + int m_iTimeoutMs; + + std::string * m_psValue; + StateMachine * m_poSM; + SMCtx * m_poSMCtx; + SerialLock m_oSerialLock; +}; +} diff --git a/src/algorithm/committer.cpp b/src/algorithm/committer.cpp new file mode 100644 index 000000000..5b2edf600 --- /dev/null +++ b/src/algorithm/committer.cpp @@ -0,0 +1,145 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "committer.h" +#include "commitctx.h" +#include "ioloop.h" +#include "commdef.h" + +namespace phxpaxos +{ + +Committer :: Committer(Config * poConfig, CommitCtx * poCommitCtx, IOLoop * poIOLoop, SMFac * poSMFac) + : m_poConfig(poConfig), m_poCommitCtx(poCommitCtx), m_poIOLoop(poIOLoop), m_poSMFac(poSMFac), m_iTimeoutMs(-1) +{ +} + +Committer :: ~Committer() +{ +} + +int Committer :: NewValue(const std::string & sValue) +{ + uint64_t llInstanceID = 0; + return NewValueGetID(sValue, llInstanceID, nullptr, nullptr); +} + +int Committer :: NewValueGetID(const std::string & sValue, uint64_t & llInstanceID) +{ + return NewValueGetID(sValue, llInstanceID, nullptr, nullptr); +} + +int Committer :: NewValueGetID(const std::string & sValue, uint64_t & llInstanceID, StateMachine * poSM, SMCtx * poSMCtx) +{ + BP->GetCommiterBP()->NewValue(); + + int iRetryCount = 3; + int ret = PaxosTryCommitRet_OK; + while(iRetryCount--) + { + TimeStat oTimeStat; + oTimeStat.Point(); + + ret = NewValueGetIDNoRetry(sValue, llInstanceID, poSM, poSMCtx); + if (ret != PaxosTryCommitRet_Conflict) + { + if (ret == 0) + { + BP->GetCommiterBP()->NewValueCommitOK(oTimeStat.Point()); + } + else + { + BP->GetCommiterBP()->NewValueCommitFail(); + } + break; + } + + BP->GetCommiterBP()->NewValueConflict(); + + if (poSMCtx != nullptr && poSMCtx->m_iSMID == MASTER_V_SMID) + { + //master sm not retry + break; + } + } + + return ret; +} + +int Committer :: NewValueGetIDNoRetry(const std::string & sValue, uint64_t & llInstanceID, + StateMachine * poSM, SMCtx * poSMCtx) +{ + int iLockUseTimeMs = 0; + bool bHasLock = m_oWaitLock.Lock(m_iTimeoutMs, iLockUseTimeMs); + if (!bHasLock) + { + BP->GetCommiterBP()->NewValueGetLockTimeout(); + PLGErr("Try get lock, but timeout, lockusetime %dms", iLockUseTimeMs); + return PaxosTryCommitRet_Timeout; + } + + int iLeftTimeoutMs = -1; + if (m_iTimeoutMs > 0) + { + iLeftTimeoutMs = m_iTimeoutMs > iLockUseTimeMs ? m_iTimeoutMs - iLockUseTimeMs : 0; + if (iLeftTimeoutMs < 100) + { + PLGErr("Get lock ok, but lockusetime %dms too long, lefttimeout %dms", iLockUseTimeMs, iLeftTimeoutMs); + + BP->GetCommiterBP()->NewValueGetLockTimeout(); + + m_oWaitLock.UnLock(); + return PaxosTryCommitRet_Timeout; + } + } + + PLGImp("GetLock ok, use time %dms", iLockUseTimeMs); + + BP->GetCommiterBP()->NewValueGetLockOK(iLockUseTimeMs); + + //pack smid to value + int iSMID = poSM != nullptr ? poSM->SMID() : 0; + if (iSMID == 0) + { + iSMID = poSMCtx != nullptr ? poSMCtx->m_iSMID : 0; + } + + string sPackSMIDValue = sValue; + m_poSMFac->PackPaxosValue(sPackSMIDValue, iSMID); + + m_poCommitCtx->NewCommit(&sPackSMIDValue, poSM, poSMCtx, iLeftTimeoutMs); + m_poIOLoop->AddNotify(); + + int ret = m_poCommitCtx->GetResult(llInstanceID); + + m_oWaitLock.UnLock(); + return ret; +} + +//////////////////////////////////////////////////// + +void Committer :: SetTimeoutMs(const int iTimeoutMs) +{ + m_iTimeoutMs = iTimeoutMs; +} + +} + diff --git a/src/algorithm/committer.h b/src/algorithm/committer.h new file mode 100644 index 000000000..8e8ec5b7e --- /dev/null +++ b/src/algorithm/committer.h @@ -0,0 +1,64 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include "comm_include.h" +#include "sm_base.h" +#include "config_include.h" + +namespace phxpaxos +{ + +class CommitCtx; +class IOLoop; + +class Committer +{ +public: + Committer(Config * poConfig, CommitCtx * poCommitCtx, IOLoop * poIOLoop, SMFac * poSMFac); + ~Committer(); + +public: + int NewValueGetID(const std::string & sValue, uint64_t & llInstanceID); + + int NewValueGetID(const std::string & sValue, uint64_t & llInstanceID, StateMachine * poSM, SMCtx * poSMCtx); + + int NewValueGetIDNoRetry(const std::string & sValue, uint64_t & llInstanceID, StateMachine * poSM, SMCtx * poSMCtx); + + int NewValue(const std::string & sValue); + +public: + void SetTimeoutMs(const int iTimeoutMs); + +private: + Config * m_poConfig; + CommitCtx * m_poCommitCtx; + IOLoop * m_poIOLoop; + SMFac * m_poSMFac; + + WaitLock m_oWaitLock; + int m_iTimeoutMs; +}; + +} diff --git a/src/algorithm/instance.cpp b/src/algorithm/instance.cpp new file mode 100644 index 000000000..b92c05f5f --- /dev/null +++ b/src/algorithm/instance.cpp @@ -0,0 +1,753 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "instance.h" +#include "proposer.h" +#include "acceptor.h" +#include "learner.h" + +namespace phxpaxos +{ + +Instance :: Instance( + const Config * poConfig, + const LogStorage * poLogStorage, + const MsgTransport * poMsgTransport, + const bool bUseCheckpointReplayer) + : m_oIOLoop((Config *)poConfig, this), + m_oAcceptor(poConfig, poMsgTransport, this, poLogStorage), + m_oLearner(poConfig, poMsgTransport, this, &m_oAcceptor, poLogStorage, &m_oIOLoop, &m_oCheckpointMgr, &m_oSMFac), + m_oProposer(poConfig, poMsgTransport, this, &m_oLearner, &m_oIOLoop), + m_oPaxosLog(poLogStorage), + m_oCommitCtx((Config *)poConfig), + m_oCommitter((Config *)poConfig, &m_oCommitCtx, &m_oIOLoop, &m_oSMFac), + m_oCheckpointMgr((Config *)poConfig, &m_oSMFac, (LogStorage *)poLogStorage, bUseCheckpointReplayer) +{ + m_poConfig = (Config *)poConfig; + m_poMsgTransport = (MsgTransport *)poMsgTransport; + m_iCommitTimerID = 0; + m_iLastChecksum = 0; +} + +Instance :: ~Instance() +{ + m_oIOLoop.Stop(); + m_oCheckpointMgr.Stop(); + m_oLearner.Stop(); + + PLGHead("Instance Deleted, GroupIdx %d.", m_poConfig->GetMyGroupIdx()); +} + +int Instance :: Init() +{ + m_oLearner.Init(); + + //Must init acceptor first, because the max instanceid is record in acceptor state. + int ret = m_oAcceptor.Init(); + if (ret != 0) + { + PLGErr("Acceptor.Init fail, ret %d", ret); + return ret; + } + + ret = m_oCheckpointMgr.Init(); + if (ret != 0) + { + PLGErr("CheckpointMgr.Init fail, ret %d", ret); + return ret; + } + + uint64_t llCPInstanceID = m_oCheckpointMgr.GetCheckpointInstanceID() + 1; + + PLGImp("Acceptor.OK, Log.InstanceID %lu Checkpoint.InstanceID %lu", + m_oAcceptor.GetInstanceID(), llCPInstanceID); + + uint64_t llNowInstanceID = llCPInstanceID; + if (llNowInstanceID < m_oAcceptor.GetInstanceID()) + { + ret = PlayLog(llNowInstanceID, m_oAcceptor.GetInstanceID()); + if (ret != 0) + { + return ret; + } + + PLGImp("PlayLog OK, begin instanceid %lu end instanceid %lu", llNowInstanceID, m_oAcceptor.GetInstanceID()); + + llNowInstanceID = m_oAcceptor.GetInstanceID(); + } + else + { + if (llNowInstanceID > m_oAcceptor.GetInstanceID()) + { + m_oAcceptor.InitForNewPaxosInstance(); + } + + m_oAcceptor.SetInstanceID(llNowInstanceID); + } + + PLGImp("NowInstanceID %lu", llNowInstanceID); + + m_oLearner.SetInstanceID(llNowInstanceID); + m_oProposer.SetInstanceID(llNowInstanceID); + m_oProposer.SetStartProposalID(m_oAcceptor.GetAcceptorState()->GetPromiseBallot().m_llProposalID + 1); + + m_oCheckpointMgr.SetMaxChosenInstanceID(llNowInstanceID); + + ret = InitLastCheckSum(); + if (ret != 0) + { + return ret; + } + + m_oLearner.Reset_AskforLearn_Noop(); + + //start ioloop + m_oIOLoop.start(); + //start checkpoint replayer and cleaner + m_oCheckpointMgr.Start(); + + PLGImp("OK"); + + return 0; +} + +int Instance :: InitLastCheckSum() +{ + if (m_oAcceptor.GetInstanceID() == 0) + { + m_iLastChecksum = 0; + return 0; + } + + if (m_oAcceptor.GetInstanceID() <= m_oCheckpointMgr.GetMinChosenInstanceID()) + { + m_iLastChecksum = 0; + return 0; + } + + AcceptorStateData oState; + int ret = m_oPaxosLog.ReadState(m_poConfig->GetMyGroupIdx(), m_oAcceptor.GetInstanceID() - 1, oState); + if (ret != 0 && ret != 1) + { + return ret; + } + + if (ret == 1) + { + PLGErr("las checksum not exist, now instanceid %lu", m_oAcceptor.GetInstanceID()); + m_iLastChecksum = 0; + return 0; + } + + m_iLastChecksum = oState.checksum(); + + PLGImp("ok, last checksum %u", m_iLastChecksum); + + return 0; +} + +int Instance :: PlayLog(const uint64_t llBeginInstanceID, const uint64_t llEndInstanceID) +{ + if (llBeginInstanceID < m_oCheckpointMgr.GetMinChosenInstanceID()) + { + PLGErr("now instanceid %lu small than min chosen instanceid %lu", + llBeginInstanceID, m_oCheckpointMgr.GetMinChosenInstanceID()); + return -2; + } + + for (uint64_t llInstanceID = llBeginInstanceID; llInstanceID < llEndInstanceID; llInstanceID++) + { + AcceptorStateData oState; + int ret = m_oPaxosLog.ReadState(m_poConfig->GetMyGroupIdx(), llInstanceID, oState); + if (ret != 0) + { + PLGErr("log read fail, instanceid %lu ret %d", llInstanceID, ret); + return ret; + } + + bool bExecuteRet = m_oSMFac.Execute(m_poConfig->GetMyGroupIdx(), llInstanceID, oState.acceptedvalue(), nullptr); + if (!bExecuteRet) + { + PLGErr("Execute fail, instanceid %lu", llInstanceID); + return -1; + } + } + + return 0; +} + +const uint32_t Instance :: GetLastChecksum() +{ + return m_iLastChecksum; +} + +Committer * Instance :: GetCommitter() +{ + return &m_oCommitter; +} + +Cleaner * Instance :: GetCheckpointCleaner() +{ + return m_oCheckpointMgr.GetCleaner(); +} + +Replayer * Instance :: GetCheckpointReplayer() +{ + return m_oCheckpointMgr.GetReplayer(); +} + +//////////////////////////////////////////////// + +void Instance :: CheckNewValue() +{ + if (!m_oCommitCtx.IsNewCommit()) + { + return; + } + + if (!m_oLearner.IsIMLatest()) + { + return; + } + + if (m_poConfig->IsIMFollower()) + { + PLGErr("I'm follower, skip this new value"); + m_oCommitCtx.SetResultOnlyRet(PaxosTryCommitRet_Follower_Cannot_Commit); + return; + } + + if (!m_poConfig->CheckConfig()) + { + PLGErr("I'm not in membership, skip this new value"); + m_oCommitCtx.SetResultOnlyRet(PaxosTryCommitRet_Im_Not_In_Membership); + return; + } + + if ((int)m_oCommitCtx.GetCommitValue().size() > MAX_VALUE_SIZE) + { + PLGErr("value size %zu to large, skip this new value", + m_oCommitCtx.GetCommitValue().size()); + m_oCommitCtx.SetResultOnlyRet(PaxosTryCommitRet_Value_Size_TooLarge); + return; + } + + m_oCommitCtx.StartCommit(m_oProposer.GetInstanceID()); + + if (m_oCommitCtx.GetTimeoutMs() != -1) + { + m_oIOLoop.AddTimer(m_oCommitCtx.GetTimeoutMs(), Timer_Instance_Commit_Timeout, m_iCommitTimerID); + } + + m_oTimeStat.Point(); + + if (m_poConfig->GetIsUseMembership() + && (m_oProposer.GetInstanceID() == 0 || m_poConfig->GetGid() == 0)) + { + //Init system variables. + PLGHead("Need to init system variables, Now.InstanceID %lu Now.Gid %lu", + m_oProposer.GetInstanceID(), m_poConfig->GetGid()); + + uint64_t llGid = OtherUtils::GenGid(m_poConfig->GetMyNodeID()); + string sInitSVOpValue; + int ret = m_poConfig->GetSystemVSM()->CreateGid_OPValue(llGid, sInitSVOpValue); + assert(ret == 0); + + m_oSMFac.PackPaxosValue(sInitSVOpValue, m_poConfig->GetSystemVSM()->SMID()); + m_oProposer.NewValue(sInitSVOpValue); + } + else + { + m_oProposer.NewValue(m_oCommitCtx.GetCommitValue()); + } +} + +void Instance :: OnNewValueCommitTimeout() +{ + BP->GetInstanceBP()->OnNewValueCommitTimeout(); + + m_oProposer.ExitPrepare(); + m_oProposer.ExitAccept(); + + m_oCommitCtx.SetResult(PaxosTryCommitRet_Timeout, m_oProposer.GetInstanceID(), ""); +} + +////////////////////////////////////////////////////////////////////// + +int Instance :: OnReceiveMessage(const char * pcMessage, const int iMessageLen) +{ + m_oIOLoop.AddMessage(pcMessage, iMessageLen); + + return 0; +} + +bool Instance :: ReceiveMsgHeaderCheck(const Header & oHeader, const nodeid_t iFromNodeID) +{ + if (m_poConfig->GetGid() == 0 || oHeader.gid() == 0) + { + return true; + } + + if (m_poConfig->GetGid() != oHeader.gid()) + { + BP->GetAlgorithmBaseBP()->HeaderGidNotSame(); + PLGErr("Header check fail, header.gid %lu config.gid %lu, msg.from_nodeid %lu", + oHeader.gid(), m_poConfig->GetGid(), iFromNodeID); + return false; + } + + return true; +} + +void Instance :: OnReceive(const std::string & sBuffer) +{ + BP->GetInstanceBP()->OnReceive(); + + if (sBuffer.size() <= 6) + { + PLGErr("buffer size %zu too short", sBuffer.size()); + return; + } + + Header oHeader; + size_t iBodyStartPos = 0; + size_t iBodyLen = 0; + int ret = Base::UnPackBaseMsg(sBuffer, oHeader, iBodyStartPos, iBodyLen); + if (ret != 0) + { + return; + } + + int iCmd = oHeader.cmdid(); + + if (iCmd == MsgCmd_PaxosMsg) + { + if (m_oCheckpointMgr.InAskforcheckpointMode()) + { + PLGImp("in ask for checkpoint mode, ignord paxosmsg"); + return; + } + + PaxosMsg oPaxosMsg; + bool bSucc = oPaxosMsg.ParseFromArray(sBuffer.data() + iBodyStartPos, iBodyLen); + if (!bSucc) + { + BP->GetInstanceBP()->OnReceiveParseError(); + PLGErr("PaxosMsg.ParseFromArray fail, skip this msg"); + return; + } + + if (!ReceiveMsgHeaderCheck(oHeader, oPaxosMsg.nodeid())) + { + return; + } + + OnReceivePaxosMsg(oPaxosMsg); + } + else if (iCmd == MsgCmd_CheckpointMsg) + { + CheckpointMsg oCheckpointMsg; + bool bSucc = oCheckpointMsg.ParseFromArray(sBuffer.data() + iBodyStartPos, iBodyLen); + if (!bSucc) + { + BP->GetInstanceBP()->OnReceiveParseError(); + PLGErr("PaxosMsg.ParseFromArray fail, skip this msg"); + return; + } + + if (!ReceiveMsgHeaderCheck(oHeader, oCheckpointMsg.nodeid())) + { + return; + } + + OnReceiveCheckpointMsg(oCheckpointMsg); + } +} + +void Instance :: OnReceiveCheckpointMsg(const CheckpointMsg & oCheckpointMsg) +{ + PLGImp("Now.InstanceID %lu MsgType %d Msg.from_nodeid %lu My.nodeid %lu flag %d" + " uuid %lu sequence %lu checksum %lu offset %lu buffsize %zu filepath %s", + m_oAcceptor.GetInstanceID(), oCheckpointMsg.msgtype(), oCheckpointMsg.nodeid(), + m_poConfig->GetMyNodeID(), oCheckpointMsg.flag(), oCheckpointMsg.uuid(), oCheckpointMsg.sequence(), oCheckpointMsg.checksum(), + oCheckpointMsg.offset(), oCheckpointMsg.buffer().size(), oCheckpointMsg.filepath().c_str()); + + if (oCheckpointMsg.msgtype() == CheckpointMsgType_SendFile) + { + if (!m_oCheckpointMgr.InAskforcheckpointMode()) + { + PLGImp("not in ask for checkpoint mode, ignord checkpoint msg"); + return; + } + + m_oLearner.OnSendCheckpoint(oCheckpointMsg); + } + else if (oCheckpointMsg.msgtype() == CheckpointMsgType_SendFile_Ack) + { + m_oLearner.OnSendCheckpointAck(oCheckpointMsg); + } +} + +int Instance :: OnReceivePaxosMsg(const PaxosMsg & oPaxosMsg) +{ + BP->GetInstanceBP()->OnReceivePaxosMsg(); + + PLGImp("Now.InstanceID %lu Msg.InstanceID %lu MsgType %d Msg.from_nodeid %lu My.nodeid %lu Seen.LatestInstanceID %lu", + m_oProposer.GetInstanceID(), oPaxosMsg.instanceid(), oPaxosMsg.msgtype(), + oPaxosMsg.nodeid(), m_poConfig->GetMyNodeID(), m_oLearner.GetSeenLatestInstanceID()); + + if (oPaxosMsg.msgtype() == MsgType_PaxosPrepareReply + || oPaxosMsg.msgtype() == MsgType_PaxosAcceptReply + || oPaxosMsg.msgtype() == MsgType_PaxosProposal_SendNewValue) + { + if (!m_poConfig->IsValidNodeID(oPaxosMsg.nodeid())) + { + BP->GetInstanceBP()->OnReceivePaxosMsgNodeIDNotValid(); + PLGErr("acceptor reply type msg, from nodeid not in my membership, skip this message"); + return 0; + } + + return ReceiveMsgForProposer(oPaxosMsg); + } + else if (oPaxosMsg.msgtype() == MsgType_PaxosPrepare + || oPaxosMsg.msgtype() == MsgType_PaxosAccept) + { + //if my gid is zero, then this is a unknown node. + if (m_poConfig->GetGid() == 0) + { + m_poConfig->AddTmpNodeOnlyForLearn(oPaxosMsg.nodeid()); + } + + if ((!m_poConfig->IsValidNodeID(oPaxosMsg.nodeid()))) + { + PLGErr("prepare/accept type msg, from nodeid not in my membership(or i'm null membership), " + "skip this message and add node to tempnode, my gid %lu", + m_poConfig->GetGid()); + + m_poConfig->AddTmpNodeOnlyForLearn(oPaxosMsg.nodeid()); + + return 0; + } + + ChecksumLogic(oPaxosMsg); + return ReceiveMsgForAcceptor(oPaxosMsg); + } + else if (oPaxosMsg.msgtype() == MsgType_PaxosLearner_AskforLearn + || oPaxosMsg.msgtype() == MsgType_PaxosLearner_SendLearnValue + || oPaxosMsg.msgtype() == MsgType_PaxosLearner_ProposerSendSuccess + || oPaxosMsg.msgtype() == MsgType_PaxosLearner_ComfirmAskforLearn + || oPaxosMsg.msgtype() == MsgType_PaxosLearner_SendNowInstanceID + || oPaxosMsg.msgtype() == MsgType_PaxosLearner_SendLearnValue_Ack + || oPaxosMsg.msgtype() == MsgType_PaxosLearner_AskforCheckpoint) + { + ChecksumLogic(oPaxosMsg); + return ReceiveMsgForLearner(oPaxosMsg); + } + else + { + BP->GetInstanceBP()->OnReceivePaxosMsgTypeNotValid(); + PLGErr("Invaid msgtype %d", oPaxosMsg.msgtype()); + } + + return 0; +} + +int Instance :: ReceiveMsgForProposer(const PaxosMsg & oPaxosMsg) +{ + if (m_poConfig->IsIMFollower()) + { + PLGErr("I'm follower, skip this message"); + return 0; + } + + /////////////////////////////////////////////////////////////// + + if (oPaxosMsg.instanceid() != m_oProposer.GetInstanceID()) + { + BP->GetInstanceBP()->OnReceivePaxosProposerMsgInotsame(); + PLGErr("InstanceID not same, skip msg"); + return 0; + } + + if (oPaxosMsg.msgtype() == MsgType_PaxosPrepareReply) + { + m_oProposer.OnPrepareReply(oPaxosMsg); + } + else if (oPaxosMsg.msgtype() == MsgType_PaxosAcceptReply) + { + m_oProposer.OnAcceptReply(oPaxosMsg); + } + + return 0; +} + +int Instance :: ReceiveMsgForAcceptor(const PaxosMsg & oPaxosMsg) +{ + if (m_poConfig->IsIMFollower()) + { + PLGErr("I'm follower, skip this message"); + return 0; + } + + ////////////////////////////////////////////////////////////// + + if (oPaxosMsg.instanceid() != m_oAcceptor.GetInstanceID()) + { + BP->GetInstanceBP()->OnReceivePaxosAcceptorMsgInotsame(); + } + + if (oPaxosMsg.instanceid() == m_oAcceptor.GetInstanceID() + 1) + { + //skip success message + PaxosMsg oNewPaxosMsg = oPaxosMsg; + oNewPaxosMsg.set_instanceid(m_oAcceptor.GetInstanceID()); + oNewPaxosMsg.set_msgtype(MsgType_PaxosLearner_ProposerSendSuccess); + + ReceiveMsgForLearner(oNewPaxosMsg); + } + + if (oPaxosMsg.instanceid() == m_oAcceptor.GetInstanceID()) + { + if (oPaxosMsg.msgtype() == MsgType_PaxosPrepare) + { + return m_oAcceptor.OnPrepare(oPaxosMsg); + } + else if (oPaxosMsg.msgtype() == MsgType_PaxosAccept) + { + m_oAcceptor.OnAccept(oPaxosMsg); + } + } + else if (oPaxosMsg.instanceid() > m_oAcceptor.GetInstanceID()) + { + if (oPaxosMsg.instanceid() >= m_oLearner.GetSeenLatestInstanceID()) + { + //need retry msg precondition + //1. prepare or accept msg + //2. msg.instanceid > nowinstanceid. + // (if < nowinstanceid, this msg is expire) + //3. msg.instanceid >= seen latestinstanceid. + // (if < seen latestinstanceid, proposer don't need reply with this instanceid anymore.) + m_oIOLoop.AddRetryPaxosMsg(oPaxosMsg); + + BP->GetInstanceBP()->OnReceivePaxosAcceptorMsgAddRetry(); + + PLGErr("InstanceID not same, get in to retry logic"); + } + } + + return 0; +} + +int Instance :: ReceiveMsgForLearner(const PaxosMsg & oPaxosMsg) +{ + if (oPaxosMsg.msgtype() == MsgType_PaxosLearner_AskforLearn) + { + m_oLearner.OnAskforLearn(oPaxosMsg); + } + else if (oPaxosMsg.msgtype() == MsgType_PaxosLearner_SendLearnValue) + { + m_oLearner.OnSendLearnValue(oPaxosMsg); + } + else if (oPaxosMsg.msgtype() == MsgType_PaxosLearner_ProposerSendSuccess) + { + m_oLearner.OnProposerSendSuccess(oPaxosMsg); + } + else if (oPaxosMsg.msgtype() == MsgType_PaxosLearner_SendNowInstanceID) + { + m_oLearner.OnSendNowInstanceID(oPaxosMsg); + } + else if (oPaxosMsg.msgtype() == MsgType_PaxosLearner_ComfirmAskforLearn) + { + m_oLearner.OnComfirmAskForLearn(oPaxosMsg); + } + else if (oPaxosMsg.msgtype() == MsgType_PaxosLearner_SendLearnValue_Ack) + { + m_oLearner.OnSendLearnValue_Ack(oPaxosMsg); + } + else if (oPaxosMsg.msgtype() == MsgType_PaxosLearner_AskforCheckpoint) + { + m_oLearner.OnAskforCheckpoint(oPaxosMsg); + } + + if (m_oLearner.IsLearned()) + { + BP->GetInstanceBP()->OnInstanceLearned(); + + StateMachine * poSM = nullptr; + SMCtx * poSMCtx = nullptr; + bool bIsMyCommit = m_oCommitCtx.IsMyCommit(m_oLearner.GetInstanceID(), m_oLearner.GetLearnValue(), poSM, poSMCtx); + + if (!bIsMyCommit) + { + BP->GetInstanceBP()->OnInstanceLearnedNotMyCommit(); + PLGDebug("this value is not my commit"); + } + else + { + int iUseTimeMs = m_oTimeStat.Point(); + BP->GetInstanceBP()->OnInstanceLearnedIsMyCommit(iUseTimeMs); + PLGHead("My commit ok, usetime %dms", iUseTimeMs); + } + + if (!SMExecute(m_oLearner.GetInstanceID(), m_oLearner.GetLearnValue(), bIsMyCommit, poSM, poSMCtx)) + { + BP->GetInstanceBP()->OnInstanceLearnedSMExecuteFail(); + + PLGErr("SMExecute fail, instanceid %lu, not increase instanceid", m_oLearner.GetInstanceID()); + m_oCommitCtx.SetResult(PaxosTryCommitRet_ExecuteFail, + m_oLearner.GetInstanceID(), m_oLearner.GetLearnValue()); + + m_oProposer.CancelSkipPrepare(); + + return -1; + } + + { + //this paxos instance end, tell proposal done + m_oCommitCtx.SetResult(PaxosTryCommitRet_OK + , m_oLearner.GetInstanceID(), m_oLearner.GetLearnValue()); + + if (m_iCommitTimerID > 0) + { + m_oIOLoop.RemoveTimer(m_iCommitTimerID); + } + } + + PLGHead("[Learned] New paxos starting, Now.Proposer.InstanceID %lu " + "Now.Acceptor.InstanceID %lu Now.Learner.InstanceID %lu", + m_oProposer.GetInstanceID(), m_oAcceptor.GetInstanceID(), m_oLearner.GetInstanceID()); + + PLGHead("[Learned] Checksum change, last checksum %u new checksum %u", + m_iLastChecksum, m_oLearner.GetNewChecksum()); + + m_iLastChecksum = m_oLearner.GetNewChecksum(); + + NewInstance(); + + PLGHead("[Learned] New paxos instance has started, Now.Proposer.InstanceID %lu " + "Now.Acceptor.InstanceID %lu Now.Learner.InstanceID %lu", + m_oProposer.GetInstanceID(), m_oAcceptor.GetInstanceID(), m_oLearner.GetInstanceID()); + + m_oCheckpointMgr.SetMaxChosenInstanceID(m_oAcceptor.GetInstanceID()); + + BP->GetInstanceBP()->NewInstance(); + } + + return 0; +} + +void Instance :: NewInstance() +{ + m_oAcceptor.NewInstance(); + m_oLearner.NewInstance(); + m_oProposer.NewInstance(); +} + +const uint64_t Instance :: GetNowInstanceID() +{ + return m_oAcceptor.GetInstanceID(); +} + +/////////////////////////////// + +void Instance :: OnTimeout(const uint32_t iTimerID, const int iType) +{ + if (iType == Timer_Proposer_Prepare_Timeout) + { + m_oProposer.OnPrepareTimeout(); + } + else if (iType == Timer_Proposer_Accept_Timeout) + { + m_oProposer.OnAcceptTimeout(); + } + else if (iType == Timer_Learner_Askforlearn_noop) + { + m_oLearner.AskforLearn_Noop(); + } + else if (iType == Timer_Instance_Commit_Timeout) + { + OnNewValueCommitTimeout(); + } + else + { + PLGErr("unknown timer type %d, timerid %u", iType, iTimerID); + } +} + +//////////////////////////////// + +void Instance :: AddStateMachine(StateMachine * poSM) +{ + m_oSMFac.AddSM(poSM); +} + +bool Instance :: SMExecute( + const uint64_t llInstanceID, + const std::string & sValue, + const bool bIsMyCommit, + StateMachine * poSM, + SMCtx * poSMCtx) +{ + if (bIsMyCommit && poSM != nullptr) + { + return m_oSMFac.DoExecute(poSM, m_poConfig->GetMyGroupIdx(), llInstanceID, sValue, poSMCtx); + } + else + { + return m_oSMFac.Execute(m_poConfig->GetMyGroupIdx(), llInstanceID, sValue, poSMCtx); + } +} + +//////////////////////////////// + +void Instance :: ChecksumLogic(const PaxosMsg & oPaxosMsg) +{ + if (oPaxosMsg.lastchecksum() == 0) + { + return; + } + + if (oPaxosMsg.instanceid() != m_oAcceptor.GetInstanceID()) + { + return; + } + + if (m_oAcceptor.GetInstanceID() > 0 && GetLastChecksum() == 0) + { + PLGErr("I have no last checksum, other last checksum %u", oPaxosMsg.lastchecksum()); + m_iLastChecksum = oPaxosMsg.lastchecksum(); + return; + } + + PLGHead("my last checksum %u other last checksum %u", GetLastChecksum(), oPaxosMsg.lastchecksum()); + + if (oPaxosMsg.lastchecksum() != GetLastChecksum()) + { + PLGErr("checksum fail, my last checksum %u other last checksum %u", + GetLastChecksum(), oPaxosMsg.lastchecksum()); + BP->GetInstanceBP()->ChecksumLogicFail(); + } + + assert(oPaxosMsg.lastchecksum() == GetLastChecksum()); +} + +} + diff --git a/src/algorithm/instance.h b/src/algorithm/instance.h new file mode 100644 index 000000000..48a35d99e --- /dev/null +++ b/src/algorithm/instance.h @@ -0,0 +1,140 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "base.h" +#include "acceptor.h" +#include "learner.h" +#include "proposer.h" +#include "msg_transport.h" +#include "phxpaxos/sm.h" +#include "sm_base.h" +#include "phxpaxos/storage.h" +#include "comm_include.h" +#include "ioloop.h" +#include "commitctx.h" +#include "committer.h" +#include "cp_mgr.h" + +namespace phxpaxos +{ + +class Instance +{ +public: + Instance( + const Config * poConfig, + const LogStorage * poLogStorage, + const MsgTransport * poMsgTransport, + const bool bUseCheckpointReplayer); + ~Instance(); + + int Init(); + + int InitLastCheckSum(); + + const uint64_t GetNowInstanceID(); + + const uint32_t GetLastChecksum(); + +public: + Committer * GetCommitter(); + + Cleaner * GetCheckpointCleaner(); + + Replayer * GetCheckpointReplayer(); + +public: + void CheckNewValue(); + + void OnNewValueCommitTimeout(); + +public: + //this funciton only enqueue, do nothing. + int OnReceiveMessage(const char * pcMessage, const int iMessageLen); + +public: + void OnReceive(const std::string & sBuffer); + + void OnReceiveCheckpointMsg(const CheckpointMsg & oCheckpointMsg); + + int OnReceivePaxosMsg(const PaxosMsg & oPaxosMsg); + + int ReceiveMsgForProposer(const PaxosMsg & oPaxosMsg); + + int ReceiveMsgForAcceptor(const PaxosMsg & oPaxosMsg); + + int ReceiveMsgForLearner(const PaxosMsg & oPaxosMsg); + +public: + void OnTimeout(const uint32_t iTimerID, const int iType); + +public: + void AddStateMachine(StateMachine * poSM); + + bool SMExecute( + const uint64_t llInstanceID, + const std::string & sValue, + const bool bIsMyCommit, + StateMachine * poSM, + SMCtx * poSMCtx); + +private: + void ChecksumLogic(const PaxosMsg & oPaxosMsg); + + int PlayLog(const uint64_t llBeginInstanceID, const uint64_t llEndInstanceID); + + bool ReceiveMsgHeaderCheck(const Header & oHeader, const nodeid_t iFromNodeID); + +private: + void NewInstance(); + +private: + Config * m_poConfig; + MsgTransport * m_poMsgTransport; + + IOLoop m_oIOLoop; + + Acceptor m_oAcceptor; + Learner m_oLearner; + Proposer m_oProposer; + + PaxosLog m_oPaxosLog; + + uint32_t m_iLastChecksum; + +private: + CommitCtx m_oCommitCtx; + uint32_t m_iCommitTimerID; + + Committer m_oCommitter; + +private: + SMFac m_oSMFac; + + CheckpointMgr m_oCheckpointMgr; + +private: + TimeStat m_oTimeStat; +}; + +} diff --git a/src/algorithm/ioloop.cpp b/src/algorithm/ioloop.cpp new file mode 100644 index 000000000..b99acce3c --- /dev/null +++ b/src/algorithm/ioloop.cpp @@ -0,0 +1,255 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "ioloop.h" +#include "utils_include.h" +#include "instance.h" + +using namespace std; + +namespace phxpaxos +{ + +IOLoop :: IOLoop(Config * poConfig, Instance * poInstance) + : m_poConfig(poConfig), m_poInstance(poInstance) +{ + m_bIsEnd = false; + m_bIsStart = false; + + m_iQueueMemSize = 0; +} + +IOLoop :: ~IOLoop() +{ +} + +void IOLoop :: run() +{ + m_bIsEnd = false; + m_bIsStart = true; + while(true) + { + BP->GetIOLoopBP()->OneLoop(); + + int iNextTimeout = 1000; + + DealwithTimeout(iNextTimeout); + + //PLGHead("nexttimeout %d", iNextTimeout); + + OneLoop(iNextTimeout); + + if (m_bIsEnd) + { + PLGHead("IOLoop [End]"); + break; + } + } +} + +void IOLoop :: AddNotify() +{ + m_oMessageQueue.lock(); + m_oMessageQueue.add(nullptr); + m_oMessageQueue.unlock(); +} + +int IOLoop :: AddMessage(const char * pcMessage, const int iMessageLen) +{ + m_oMessageQueue.lock(); + + BP->GetIOLoopBP()->EnqueueMsg(); + + if ((int)m_oMessageQueue.size() > QUEUE_MAXLENGTH) + { + BP->GetIOLoopBP()->EnqueueMsgRejectByFullQueue(); + + PLGErr("Queue full, skip msg"); + m_oMessageQueue.unlock(); + return -2; + } + + if (m_iQueueMemSize > MAX_QUEUE_MEM_SIZE) + { + PLErr("queue memsize %d too large, can't enqueue", m_iQueueMemSize); + m_oMessageQueue.unlock(); + return -2; + } + + m_oMessageQueue.add(new string(pcMessage, iMessageLen)); + + m_iQueueMemSize += iMessageLen; + + m_oMessageQueue.unlock(); + + return 0; +} + +int IOLoop :: AddRetryPaxosMsg(const PaxosMsg & oPaxosMsg) +{ + BP->GetIOLoopBP()->EnqueueRetryMsg(); + + if (m_oRetryQueue.size() > 100) + { + BP->GetIOLoopBP()->EnqueueRetryMsgRejectByFullQueue(); + return -2; + } + + m_oRetryQueue.push(oPaxosMsg); + return 0; +} + +void IOLoop :: Stop() +{ + m_bIsEnd = true; + if (m_bIsStart) + { + join(); + } +} + +void IOLoop :: DealWithRetry() +{ + if (m_oRetryQueue.empty()) + { + return; + } + + while (!m_oRetryQueue.empty()) + { + PaxosMsg & oPaxosMsg = m_oRetryQueue.front(); + if (oPaxosMsg.instanceid() <= m_poInstance->GetNowInstanceID()) + { + if (oPaxosMsg.instanceid() == m_poInstance->GetNowInstanceID()) + { + BP->GetIOLoopBP()->DealWithRetryMsg(); + PLGHead("retry msg. instanceid %lu", oPaxosMsg.instanceid()); + m_poInstance->OnReceivePaxosMsg(oPaxosMsg); + } + + m_oRetryQueue.pop(); + } + else + { + break; + } + } +} + +void IOLoop :: OneLoop(const int iTimeoutMs) +{ + std::string * psMessage = nullptr; + + m_oMessageQueue.lock(); + bool bSucc = m_oMessageQueue.peek(psMessage, iTimeoutMs); + + if (!bSucc) + { + m_oMessageQueue.unlock(); + } + else + { + m_oMessageQueue.pop(); + m_oMessageQueue.unlock(); + + if (psMessage != nullptr && psMessage->size() > 0) + { + m_iQueueMemSize -= psMessage->size(); + m_poInstance->OnReceive(*psMessage); + } + + delete psMessage; + + BP->GetIOLoopBP()->OutQueueMsg(); + } + + DealWithRetry(); + + //must put on here + //because addtimer on this funciton + m_poInstance->CheckNewValue(); +} + +bool IOLoop :: AddTimer(const int iTimeout, const int iType, uint32_t & iTimerID) +{ + if (iTimeout == -1) + { + return true; + } + + uint64_t llAbsTime = Time::GetTimestampMS() + iTimeout; + m_oTimer.AddTimerWithType(llAbsTime, iType, iTimerID); + + m_mapTimerIDExist[iTimerID] = true; + + return true; +} + +void IOLoop :: RemoveTimer(uint32_t & iTimerID) +{ + auto it = m_mapTimerIDExist.find(iTimerID); + if (it != end(m_mapTimerIDExist)) + { + m_mapTimerIDExist.erase(it); + } + + iTimerID = 0; +} + +void IOLoop :: DealwithTimeoutOne(const uint32_t iTimerID, const int iType) +{ + auto it = m_mapTimerIDExist.find(iTimerID); + if (it == end(m_mapTimerIDExist)) + { + //PLGErr("Timeout aready remove!, timerid %u iType %d", iTimerID, iType); + return; + } + + m_mapTimerIDExist.erase(it); + + m_poInstance->OnTimeout(iTimerID, iType); +} + +void IOLoop :: DealwithTimeout(int & iNextTimeout) +{ + bool bHasTimeout = true; + + while(bHasTimeout) + { + uint32_t iTimerID = 0; + int iType = 0; + bHasTimeout = m_oTimer.PopTimeout(iTimerID, iType); + + if (bHasTimeout) + { + DealwithTimeoutOne(iTimerID, iType); + + iNextTimeout = m_oTimer.GetNextTimeout(); + if (iNextTimeout != 0) + { + break; + } + } + } +} + +} + diff --git a/src/algorithm/ioloop.h b/src/algorithm/ioloop.h new file mode 100644 index 000000000..8fcdf6924 --- /dev/null +++ b/src/algorithm/ioloop.h @@ -0,0 +1,82 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include "timer.h" +#include "utils_include.h" +#include +#include "comm_include.h" +#include +#include "config_include.h" + +namespace phxpaxos +{ + +class Instance; + +class IOLoop : public Thread +{ +public: + IOLoop(Config * poConfig, Instance * poInstance); + virtual ~IOLoop(); + + void run(); + + void Stop(); + + void OneLoop(const int iTimeoutMs); + + void DealWithRetry(); + +public: + int AddMessage(const char * pcMessage, const int iMessageLen); + + int AddRetryPaxosMsg(const PaxosMsg & oPaxosMsg); + + void AddNotify(); + +public: + virtual bool AddTimer(const int iTimeout, const int iType, uint32_t & iTimerID); + + virtual void RemoveTimer(uint32_t & iTimerID); + + void DealwithTimeout(int & iNextTimeout); + + void DealwithTimeoutOne(const uint32_t iTimerID, const int iType); + +private: + bool m_bIsEnd; + bool m_bIsStart; + Timer m_oTimer; + std::map m_mapTimerIDExist; + + Queue m_oMessageQueue; + std::queue m_oRetryQueue; + + int m_iQueueMemSize; + + Config * m_poConfig; + Instance * m_poInstance; +}; + +} diff --git a/src/algorithm/learner.cpp b/src/algorithm/learner.cpp new file mode 100644 index 000000000..52e042eb1 --- /dev/null +++ b/src/algorithm/learner.cpp @@ -0,0 +1,922 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "learner.h" +#include "acceptor.h" +#include "crc32.h" +#include "cp_mgr.h" +#include "sm_base.h" + +namespace phxpaxos +{ + +LearnerState :: LearnerState(const Config * poConfig, const LogStorage * poLogStorage) + : m_oPaxosLog(poLogStorage) +{ + m_poConfig = (Config *)poConfig; + + Init(); +} + +LearnerState :: ~LearnerState() +{ +} + +void LearnerState :: Init() +{ + m_sLearnedValue = ""; + m_bIsLearned = false; + m_iNewChecksum = 0; +} + +const uint32_t LearnerState :: GetNewChecksum() const +{ + return m_iNewChecksum; +} + +void LearnerState :: LearnValueWithoutWrite(const uint64_t llInstanceID, + const std::string & sValue, const uint32_t iNewChecksum) +{ + m_sLearnedValue = sValue; + m_bIsLearned = true; + m_iNewChecksum = iNewChecksum; +} + +int LearnerState :: LearnValue(const uint64_t llInstanceID, const BallotNumber & oLearnedBallot, + const std::string & sValue, const uint32_t iLastChecksum) +{ + if (llInstanceID > 0 && iLastChecksum == 0) + { + m_iNewChecksum = 0; + } + else if (sValue.size() > 0) + { + m_iNewChecksum = crc32(iLastChecksum, (const uint8_t *)sValue.data(), sValue.size(), CRC32SKIP); + } + + AcceptorStateData oState; + oState.set_instanceid(llInstanceID); + oState.set_acceptedvalue(sValue); + oState.set_promiseid(oLearnedBallot.m_llProposalID); + oState.set_promisenodeid(oLearnedBallot.m_llNodeID); + oState.set_acceptedid(oLearnedBallot.m_llProposalID); + oState.set_acceptednodeid(oLearnedBallot.m_llNodeID); + oState.set_checksum(m_iNewChecksum); + + WriteOptions oWriteOptions; + oWriteOptions.bSync = false; + + int ret = m_oPaxosLog.WriteState(oWriteOptions, m_poConfig->GetMyGroupIdx(), llInstanceID, oState); + if (ret != 0) + { + PLGErr("LogStorage.WriteLog fail, InstanceID %lu ValueLen %zu ret %d", + llInstanceID, sValue.size(), ret); + return ret; + } + + LearnValueWithoutWrite(llInstanceID, sValue, m_iNewChecksum); + + PLGDebug("OK, InstanceID %lu ValueLen %zu checksum %u", + llInstanceID, sValue.size(), m_iNewChecksum); + + return 0; +} + +const std::string & LearnerState :: GetLearnValue() +{ + return m_sLearnedValue; +} + +const bool LearnerState :: GetIsLearned() +{ + return m_bIsLearned; +} + +////////////////////////////////////////////////////////////////////////////// + +Learner :: Learner( + const Config * poConfig, + const MsgTransport * poMsgTransport, + const Instance * poInstance, + const Acceptor * poAcceptor, + const LogStorage * poLogStorage, + const IOLoop * poIOLoop, + const CheckpointMgr * poCheckpointMgr, + const SMFac * poSMFac) + : Base(poConfig, poMsgTransport, poInstance), m_oLearnerState(poConfig, poLogStorage), + m_oPaxosLog(poLogStorage), m_oLearnerSender((Config *)poConfig, this, &m_oPaxosLog), + m_oCheckpointReceiver((Config *)poConfig, (LogStorage *)poLogStorage) +{ + m_poAcceptor = (Acceptor *)poAcceptor; + InitForNewPaxosInstance(); + + m_iAskforlearn_noopTimerID = 0; + m_poIOLoop = (IOLoop *)poIOLoop; + + m_poCheckpointMgr = (CheckpointMgr *)poCheckpointMgr; + m_poSMFac = (SMFac *)poSMFac; + m_poCheckpointSender = nullptr; + + m_llHighestSeenInstanceID = 0; + m_iHighestSeenInstanceID_FromNodeID = nullnode; + + m_bIsIMLearning = false; + + m_llLastAckInstanceID = 0; +} + +Learner :: ~Learner() +{ + delete m_poCheckpointSender; +} + +void Learner :: Init() +{ + m_oLearnerSender.start(); +} + +const bool Learner :: IsLearned() +{ + return m_oLearnerState.GetIsLearned(); +} + +const std::string & Learner :: GetLearnValue() +{ + return m_oLearnerState.GetLearnValue(); +} + +void Learner :: InitForNewPaxosInstance() +{ + m_oLearnerState.Init(); +} + +const uint32_t Learner :: GetNewChecksum() const +{ + return m_oLearnerState.GetNewChecksum(); +} + +//////////////////////////////////////////////////////////////// + +void Learner :: Stop() +{ + m_oLearnerSender.Stop(); + if (m_poCheckpointSender != nullptr) + { + m_poCheckpointSender->Stop(); + } +} + +//////////////////////////////////////////////////////////////// + +const bool Learner :: IsIMLatest() +{ + return (GetInstanceID() + 1) >= m_llHighestSeenInstanceID; +} + +const uint64_t Learner :: GetSeenLatestInstanceID() +{ + return m_llHighestSeenInstanceID; +} + +void Learner :: SetSeenInstanceID(const uint64_t llInstanceID, const nodeid_t llFromNodeID) +{ + if (llInstanceID > m_llHighestSeenInstanceID) + { + m_llHighestSeenInstanceID = llInstanceID; + m_iHighestSeenInstanceID_FromNodeID = llFromNodeID; + } +} + +////////////////////////////////////////////////////////////// + +void Learner :: Reset_AskforLearn_Noop(const int iTimeout) +{ + if (m_iAskforlearn_noopTimerID > 0) + { + m_poIOLoop->RemoveTimer(m_iAskforlearn_noopTimerID); + } + + m_poIOLoop->AddTimer(iTimeout, Timer_Learner_Askforlearn_noop, m_iAskforlearn_noopTimerID); +} + +void Learner :: AskforLearn_Noop(const bool bIsStart) +{ + Reset_AskforLearn_Noop(); + + m_bIsIMLearning = false; + + m_poCheckpointMgr->ExitCheckpointMode(); + + AskforLearn(); + + if (bIsStart) + { + AskforLearn(); + } +} + +/////////////////////////////////////////////////////////////// + +void Learner :: AskforLearn() +{ + BP->GetLearnerBP()->AskforLearn(); + + PLGHead("START"); + + PaxosMsg oPaxosMsg; + + oPaxosMsg.set_instanceid(GetInstanceID()); + oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oPaxosMsg.set_msgtype(MsgType_PaxosLearner_AskforLearn); + + if (m_poConfig->IsIMFollower()) + { + //this is not proposal nodeid, just use this val to bring followto nodeid info. + oPaxosMsg.set_proposalnodeid(m_poConfig->GetFollowToNodeID()); + } + + PLGHead("END InstanceID %lu MyNodeID %lu", oPaxosMsg.instanceid(), oPaxosMsg.nodeid()); + + BroadcastMessage(oPaxosMsg, BroadcastMessage_Type_RunSelf_None, Message_SendType_TCP); + BroadcastMessageToTempNode(oPaxosMsg, Message_SendType_UDP); +} + +void Learner :: OnAskforLearn(const PaxosMsg & oPaxosMsg) +{ + BP->GetLearnerBP()->OnAskforLearn(); + + PLGHead("START Msg.InstanceID %lu Now.InstanceID %lu Msg.from_nodeid %lu MinChosenInstanceID %lu", + oPaxosMsg.instanceid(), GetInstanceID(), oPaxosMsg.nodeid(), + m_poCheckpointMgr->GetMinChosenInstanceID()); + + SetSeenInstanceID(oPaxosMsg.instanceid(), oPaxosMsg.nodeid()); + + if (oPaxosMsg.proposalnodeid() == m_poConfig->GetMyNodeID()) + { + //Found a node follow me. + PLImp("Found a node %lu follow me.", oPaxosMsg.nodeid()); + m_poConfig->AddFollowerNode(oPaxosMsg.nodeid()); + } + + if (oPaxosMsg.instanceid() >= GetInstanceID()) + { + return; + } + + if (oPaxosMsg.instanceid() >= m_poCheckpointMgr->GetMinChosenInstanceID()) + { + if (!m_oLearnerSender.Prepare(oPaxosMsg.instanceid(), oPaxosMsg.nodeid())) + { + BP->GetLearnerBP()->OnAskforLearnGetLockFail(); + + PLGErr("LearnerSender working for others."); + + if (oPaxosMsg.instanceid() == (GetInstanceID() - 1)) + { + PLGImp("InstanceID only difference one, just send this value to other."); + //send one value + AcceptorStateData oState; + int ret = m_oPaxosLog.ReadState(m_poConfig->GetMyGroupIdx(), oPaxosMsg.instanceid(), oState); + if (ret == 0) + { + BallotNumber oBallot(oState.acceptedid(), oState.acceptednodeid()); + SendLearnValue(oPaxosMsg.nodeid(), oPaxosMsg.instanceid(), oBallot, oState.acceptedvalue(), 0); + } + } + + return; + } + } + + SendNowInstanceID(oPaxosMsg.instanceid(), oPaxosMsg.nodeid()); +} + +void Learner :: SendNowInstanceID(const uint64_t llInstanceID, const nodeid_t iSendNodeID) +{ + BP->GetLearnerBP()->SendNowInstanceID(); + + PaxosMsg oPaxosMsg; + oPaxosMsg.set_instanceid(llInstanceID); + oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oPaxosMsg.set_msgtype(MsgType_PaxosLearner_SendNowInstanceID); + oPaxosMsg.set_nowinstanceid(GetInstanceID()); + oPaxosMsg.set_minchoseninstanceid(m_poCheckpointMgr->GetMinChosenInstanceID()); + + if ((GetInstanceID() - llInstanceID) > 50) + { + //instanceid too close not need to send vsm/master checkpoint. + string sSystemVariablesCPBuffer; + int ret = m_poConfig->GetSystemVSM()->GetCheckpointBuffer(sSystemVariablesCPBuffer); + if (ret == 0) + { + oPaxosMsg.set_systemvariables(sSystemVariablesCPBuffer); + } + + string sMasterVariablesCPBuffer; + if (m_poConfig->GetMasterSM() != nullptr) + { + int ret = m_poConfig->GetMasterSM()->GetCheckpointBuffer(sMasterVariablesCPBuffer); + if (ret == 0) + { + oPaxosMsg.set_mastervariables(sMasterVariablesCPBuffer); + } + } + } + + SendMessage(iSendNodeID, oPaxosMsg); +} + +void Learner :: OnSendNowInstanceID(const PaxosMsg & oPaxosMsg) +{ + BP->GetLearnerBP()->OnSendNowInstanceID(); + + PLGHead("START Msg.InstanceID %lu Now.InstanceID %lu Msg.from_nodeid %lu Msg.MaxInstanceID %lu systemvariables_size %zu mastervariables_size %zu", + oPaxosMsg.instanceid(), GetInstanceID(), oPaxosMsg.nodeid(), oPaxosMsg.nowinstanceid(), + oPaxosMsg.systemvariables().size(), oPaxosMsg.mastervariables().size()); + + SetSeenInstanceID(oPaxosMsg.nowinstanceid(), oPaxosMsg.nodeid()); + + bool bSystemVariablesChange = false; + int ret = m_poConfig->GetSystemVSM()->UpdateByCheckpoint(oPaxosMsg.systemvariables(), bSystemVariablesChange); + if (ret == 0 && bSystemVariablesChange) + { + PLGHead("SystemVariables changed!, all thing need to reflesh, so skip this msg"); + return; + } + + bool bMasterVariablesChange = false; + if (m_poConfig->GetMasterSM() != nullptr) + { + ret = m_poConfig->GetMasterSM()->UpdateByCheckpoint(oPaxosMsg.mastervariables(), bMasterVariablesChange); + if (ret == 0 && bMasterVariablesChange) + { + PLGHead("MasterVariables changed!"); + } + } + + if (oPaxosMsg.instanceid() != GetInstanceID()) + { + PLGErr("Lag msg, skip"); + return; + } + + if (oPaxosMsg.nowinstanceid() <= GetInstanceID()) + { + PLGErr("Lag msg, skip"); + return; + } + + if (oPaxosMsg.minchoseninstanceid() > GetInstanceID()) + { + BP->GetCheckpointBP()->NeedAskforCheckpoint(); + + PLGHead("my instanceid %lu small than other's minchoseninstanceid %lu, other nodeid %lu", + GetInstanceID(), oPaxosMsg.minchoseninstanceid(), oPaxosMsg.nodeid()); + + AskforCheckpoint(oPaxosMsg.nodeid()); + } + else if (!m_bIsIMLearning) + { + ComfirmAskForLearn(oPaxosMsg.nodeid()); + } +} + +//////////////////////////////////////////// + +void Learner :: ComfirmAskForLearn(const nodeid_t iSendNodeID) +{ + BP->GetLearnerBP()->ComfirmAskForLearn(); + + PLGHead("START"); + + PaxosMsg oPaxosMsg; + + oPaxosMsg.set_instanceid(GetInstanceID()); + oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oPaxosMsg.set_msgtype(MsgType_PaxosLearner_ComfirmAskforLearn); + + PLGHead("END InstanceID %lu MyNodeID %lu", GetInstanceID(), oPaxosMsg.nodeid()); + + SendMessage(iSendNodeID, oPaxosMsg); + + m_bIsIMLearning = true; +} + +void Learner :: OnComfirmAskForLearn(const PaxosMsg & oPaxosMsg) +{ + BP->GetLearnerBP()->OnComfirmAskForLearn(); + + PLGHead("START Msg.InstanceID %lu Msg.from_nodeid %lu", oPaxosMsg.instanceid(), oPaxosMsg.nodeid()); + + if (!m_oLearnerSender.Comfirm(oPaxosMsg.instanceid(), oPaxosMsg.nodeid())) + { + BP->GetLearnerBP()->OnComfirmAskForLearnGetLockFail(); + + PLGErr("LearnerSender comfirm fail, maybe is lag msg"); + return; + } + + PLGImp("OK, success comfirm"); +} + +int Learner :: SendLearnValue( + const nodeid_t iSendNodeID, + const uint64_t llLearnInstanceID, + const BallotNumber & oLearnedBallot, + const std::string & sLearnedValue, + const uint32_t iChecksum, + const bool bNeedAck) +{ + BP->GetLearnerBP()->SendLearnValue(); + + PaxosMsg oPaxosMsg; + + oPaxosMsg.set_msgtype(MsgType_PaxosLearner_SendLearnValue); + oPaxosMsg.set_instanceid(llLearnInstanceID); + oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oPaxosMsg.set_proposalnodeid(oLearnedBallot.m_llNodeID); + oPaxosMsg.set_proposalid(oLearnedBallot.m_llProposalID); + oPaxosMsg.set_value(sLearnedValue); + oPaxosMsg.set_lastchecksum(iChecksum); + if (bNeedAck) + { + oPaxosMsg.set_flag(PaxosMsgFlagType_SendLearnValue_NeedAck); + } + + return SendMessage(iSendNodeID, oPaxosMsg, Message_SendType_TCP); +} + +void Learner :: OnSendLearnValue(const PaxosMsg & oPaxosMsg) +{ + BP->GetLearnerBP()->OnSendLearnValue(); + + PLGHead("START Msg.InstanceID %lu Now.InstanceID %lu Msg.ballot_proposalid %lu Msg.ballot_nodeid %lu Msg.ValueSize %zu", + oPaxosMsg.instanceid(), GetInstanceID(), oPaxosMsg.proposalid(), + oPaxosMsg.nodeid(), oPaxosMsg.value().size()); + + if (oPaxosMsg.instanceid() > GetInstanceID()) + { + PLGDebug("[Latest Msg] i can't learn"); + return; + } + else if (oPaxosMsg.instanceid() < GetInstanceID()) + { + PLGDebug("[Lag Msg] no need to learn"); + return; + } + + //learn value + BallotNumber oBallot(oPaxosMsg.proposalid(), oPaxosMsg.proposalnodeid()); + int ret = m_oLearnerState.LearnValue(oPaxosMsg.instanceid(), oBallot, oPaxosMsg.value(), GetLastChecksum()); + if (ret != 0) + { + PLGErr("LearnState.LearnValue fail, ret %d", ret); + return; + } + + PLGHead("END LearnValue OK, proposalid %lu proposalid_nodeid %lu valueLen %zu", + oPaxosMsg.proposalid(), oPaxosMsg.nodeid(), oPaxosMsg.value().size()); + + if (oPaxosMsg.flag() == PaxosMsgFlagType_SendLearnValue_NeedAck) + { + //every time' when receive valid need ack learn value, reset noop timeout. + Reset_AskforLearn_Noop(); + + SendLearnValue_Ack(oPaxosMsg.nodeid()); + } +} + +void Learner :: SendLearnValue_Ack(const nodeid_t iSendNodeID) +{ + PLGHead("START LastAck.Instanceid %lu Now.Instanceid %lu", m_llLastAckInstanceID, GetInstanceID()); + + if (GetInstanceID() < m_llLastAckInstanceID + SENDLEARNVALUE_ACK_LEAD) + { + PLGImp("No need to ack"); + return; + } + + BP->GetLearnerBP()->SendLearnValue_Ack(); + + m_llLastAckInstanceID = GetInstanceID(); + + PaxosMsg oPaxosMsg; + oPaxosMsg.set_instanceid(GetInstanceID()); + oPaxosMsg.set_msgtype(MsgType_PaxosLearner_SendLearnValue_Ack); + oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + + SendMessage(iSendNodeID, oPaxosMsg); + + PLGHead("End. ok"); +} + +void Learner :: OnSendLearnValue_Ack(const PaxosMsg & oPaxosMsg) +{ + BP->GetLearnerBP()->OnSendLearnValue_Ack(); + + PLGHead("Msg.Ack.Instanceid %lu Msg.from_nodeid %lu", oPaxosMsg.instanceid(), oPaxosMsg.nodeid()); + + m_oLearnerSender.Ack(oPaxosMsg.instanceid(), oPaxosMsg.nodeid()); +} + +////////////////////////////////////////////////////////////// + +void Learner :: TransmitToFollower() +{ + if (m_poConfig->GetMyFollowerCount() == 0) + { + return; + } + + PaxosMsg oPaxosMsg; + + oPaxosMsg.set_msgtype(MsgType_PaxosLearner_SendLearnValue); + oPaxosMsg.set_instanceid(GetInstanceID()); + oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oPaxosMsg.set_proposalnodeid(m_poAcceptor->GetAcceptorState()->GetAcceptedBallot().m_llNodeID); + oPaxosMsg.set_proposalid(m_poAcceptor->GetAcceptorState()->GetAcceptedBallot().m_llProposalID); + oPaxosMsg.set_value(m_poAcceptor->GetAcceptorState()->GetAcceptedValue()); + oPaxosMsg.set_lastchecksum(GetLastChecksum()); + + BroadcastMessageToFollower(oPaxosMsg, Message_SendType_TCP); + + PLGHead("ok"); +} + +void Learner :: ProposerSendSuccess( + const uint64_t llLearnInstanceID, + const uint64_t llProposalID) +{ + BP->GetLearnerBP()->ProposerSendSuccess(); + + PaxosMsg oPaxosMsg; + + oPaxosMsg.set_msgtype(MsgType_PaxosLearner_ProposerSendSuccess); + oPaxosMsg.set_instanceid(llLearnInstanceID); + oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oPaxosMsg.set_proposalid(llProposalID); + oPaxosMsg.set_lastchecksum(GetLastChecksum()); + + //run self first + BroadcastMessage(oPaxosMsg, BroadcastMessage_Type_RunSelf_First); +} + +void Learner :: OnProposerSendSuccess(const PaxosMsg & oPaxosMsg) +{ + BP->GetLearnerBP()->OnProposerSendSuccess(); + + PLGHead("START Msg.InstanceID %lu Now.InstanceID %lu Msg.ProposalID %lu State.AcceptedID %lu " + "State.AcceptedNodeID %lu, Msg.from_nodeid %lu", + oPaxosMsg.instanceid(), GetInstanceID(), oPaxosMsg.proposalid(), + m_poAcceptor->GetAcceptorState()->GetAcceptedBallot().m_llProposalID, + m_poAcceptor->GetAcceptorState()->GetAcceptedBallot().m_llNodeID, + oPaxosMsg.nodeid()); + + if (oPaxosMsg.instanceid() != GetInstanceID()) + { + //Instance id not same, that means not in the same instance, ignord. + PLGDebug("InstanceID not same, skip msg"); + return; + } + + if (m_poAcceptor->GetAcceptorState()->GetAcceptedBallot().isnull()) + { + //Not accept any yet. + BP->GetLearnerBP()->OnProposerSendSuccessNotAcceptYet(); + PLGDebug("I haven't accpeted any proposal"); + return; + } + + BallotNumber oBallot(oPaxosMsg.proposalid(), oPaxosMsg.nodeid()); + + if (m_poAcceptor->GetAcceptorState()->GetAcceptedBallot() + != oBallot) + { + //Proposalid not same, this accept value maybe not chosen value. + PLGDebug("ProposalBallot not same to AcceptedBallot"); + BP->GetLearnerBP()->OnProposerSendSuccessBallotNotSame(); + return; + } + + //learn value. + m_oLearnerState.LearnValueWithoutWrite( + oPaxosMsg.instanceid(), + m_poAcceptor->GetAcceptorState()->GetAcceptedValue(), + m_poAcceptor->GetAcceptorState()->GetChecksum()); + + BP->GetLearnerBP()->OnProposerSendSuccessSuccessLearn(); + + PLGHead("END Learn value OK, value %zu", m_poAcceptor->GetAcceptorState()->GetAcceptedValue().size()); + + TransmitToFollower(); +} + +//////////////////////////////////////////////////////////////////////// + +void Learner :: AskforCheckpoint(const nodeid_t iSendNodeID) +{ + PLGHead("START"); + + int ret = m_poCheckpointMgr->PrepareForAskforCheckpoint(iSendNodeID); + if (ret != 0) + { + return; + } + + PaxosMsg oPaxosMsg; + + oPaxosMsg.set_instanceid(GetInstanceID()); + oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oPaxosMsg.set_msgtype(MsgType_PaxosLearner_AskforCheckpoint); + + PLGHead("END InstanceID %lu MyNodeID %lu", GetInstanceID(), oPaxosMsg.nodeid()); + + SendMessage(iSendNodeID, oPaxosMsg); +} + +void Learner :: OnAskforCheckpoint(const PaxosMsg & oPaxosMsg) +{ + CheckpointSender * poCheckpointSender = GetNewCheckpointSender(oPaxosMsg.nodeid()); + if (poCheckpointSender != nullptr) + { + poCheckpointSender->start(); + PLGHead("new checkpoint sender started, send to nodeid %lu", oPaxosMsg.nodeid()); + } + else + { + PLGErr("Checkpoint Sender is running"); + } +} + +int Learner :: SendCheckpointBegin( + const nodeid_t iSendNodeID, + const uint64_t llUUID, + const uint64_t llSequence, + const uint64_t llCheckpointInstanceID) +{ + CheckpointMsg oCheckpointMsg; + + oCheckpointMsg.set_msgtype(CheckpointMsgType_SendFile); + oCheckpointMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oCheckpointMsg.set_flag(CheckpointSendFileFlag_BEGIN); + oCheckpointMsg.set_uuid(llUUID); + oCheckpointMsg.set_sequence(llSequence); + oCheckpointMsg.set_checkpointinstanceid(llCheckpointInstanceID); + + PLGImp("END, SendNodeID %lu uuid %lu sequence %lu cpi %lu", + iSendNodeID, llUUID, llSequence, llCheckpointInstanceID); + + return SendMessage(iSendNodeID, oCheckpointMsg, Message_SendType_TCP); +} + +int Learner :: SendCheckpointEnd( + const nodeid_t iSendNodeID, + const uint64_t llUUID, + const uint64_t llSequence, + const uint64_t llCheckpointInstanceID) +{ + CheckpointMsg oCheckpointMsg; + + oCheckpointMsg.set_msgtype(CheckpointMsgType_SendFile); + oCheckpointMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oCheckpointMsg.set_flag(CheckpointSendFileFlag_END); + oCheckpointMsg.set_uuid(llUUID); + oCheckpointMsg.set_sequence(llSequence); + oCheckpointMsg.set_checkpointinstanceid(llCheckpointInstanceID); + + PLGImp("END, SendNodeID %lu uuid %lu sequence %lu cpi %lu", + iSendNodeID, llUUID, llSequence, llCheckpointInstanceID); + + return SendMessage(iSendNodeID, oCheckpointMsg, Message_SendType_TCP); +} + +int Learner :: SendCheckpoint( + const nodeid_t iSendNodeID, + const uint64_t llUUID, + const uint64_t llSequence, + const uint64_t llCheckpointInstanceID, + const uint32_t iChecksum, + const std::string & sFilePath, + const int iSMID, + const uint64_t llOffset, + const std::string & sBuffer) +{ + CheckpointMsg oCheckpointMsg; + + oCheckpointMsg.set_msgtype(CheckpointMsgType_SendFile); + oCheckpointMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oCheckpointMsg.set_flag(CheckpointSendFileFlag_ING); + oCheckpointMsg.set_uuid(llUUID); + oCheckpointMsg.set_sequence(llSequence); + oCheckpointMsg.set_checkpointinstanceid(llCheckpointInstanceID); + oCheckpointMsg.set_checksum(iChecksum); + oCheckpointMsg.set_filepath(sFilePath); + oCheckpointMsg.set_smid(iSMID); + oCheckpointMsg.set_offset(llOffset); + oCheckpointMsg.set_buffer(sBuffer); + + PLGImp("END, SendNodeID %lu uuid %lu sequence %lu cpi %lu checksum %u smid %d offset %lu buffsize %zu filepath %s", + iSendNodeID, llUUID, llSequence, llCheckpointInstanceID, + iChecksum, iSMID, llOffset, sBuffer.size(), sFilePath.c_str()); + + return SendMessage(iSendNodeID, oCheckpointMsg, Message_SendType_TCP); +} + +int Learner :: OnSendCheckpoint_Begin(const CheckpointMsg & oCheckpointMsg) +{ + int ret = m_oCheckpointReceiver.NewReceiver(oCheckpointMsg.nodeid(), oCheckpointMsg.uuid()); + if (ret == 0) + { + PLGImp("NewReceiver ok"); + + ret = m_poCheckpointMgr->SetMinChosenInstanceID(oCheckpointMsg.checkpointinstanceid()); + if (ret != 0) + { + PLGErr("SetMinChosenInstanceID fail, ret %d CheckpointInstanceID %lu", + ret, oCheckpointMsg.checkpointinstanceid()); + + return ret; + } + } + + return ret; +} + +int Learner :: OnSendCheckpoint_Ing(const CheckpointMsg & oCheckpointMsg) +{ + BP->GetCheckpointBP()->OnSendCheckpointOneBlock(); + return m_oCheckpointReceiver.ReceiveCheckpoint(oCheckpointMsg); +} + +int Learner :: OnSendCheckpoint_End(const CheckpointMsg & oCheckpointMsg) +{ + if (!m_oCheckpointReceiver.IsReceiverFinish(oCheckpointMsg.nodeid(), + oCheckpointMsg.uuid(), oCheckpointMsg.sequence())) + { + PLGErr("receive end msg but receiver not finish"); + return -1; + } + + BP->GetCheckpointBP()->ReceiveCheckpointDone(); + + std::vector vecSMList = m_poSMFac->GetSMList(); + for (auto & poSM : vecSMList) + { + if (poSM->SMID() == SYSTEM_V_SMID + || poSM->SMID() == MASTER_V_SMID) + { + //system variables sm no checkpoint + //master variables sm no checkpoint + continue; + } + + string sTmpDirPath = m_oCheckpointReceiver.GetTmpDirPath(poSM->SMID()); + std::vector vecFilePathList; + + int ret = FileUtils :: IterDir(sTmpDirPath, vecFilePathList); + if (ret != 0) + { + PLGErr("IterDir fail, dirpath %s", sTmpDirPath.c_str()); + } + + if (vecFilePathList.size() == 0) + { + PLGImp("this sm %d have no checkpoint", poSM->SMID()); + continue; + } + + ret = poSM->LoadCheckpointState( + m_poConfig->GetMyGroupIdx(), + sTmpDirPath, + vecFilePathList, + oCheckpointMsg.checkpointinstanceid()); + if (ret != 0) + { + BP->GetCheckpointBP()->ReceiveCheckpointAndLoadFail(); + return ret; + } + + } + + BP->GetCheckpointBP()->ReceiveCheckpointAndLoadSucc(); + PLGImp("All sm load state ok, start to exit process"); + exit(-1); + + return 0; +} + +void Learner :: OnSendCheckpoint(const CheckpointMsg & oCheckpointMsg) +{ + PLGHead("START uuid %lu flag %d sequence %lu cpi %lu checksum %u smid %d offset %lu buffsize %zu filepath %s", + oCheckpointMsg.uuid(), oCheckpointMsg.flag(), oCheckpointMsg.sequence(), + oCheckpointMsg.checkpointinstanceid(), oCheckpointMsg.checksum(), oCheckpointMsg.smid(), + oCheckpointMsg.offset(), oCheckpointMsg.buffer().size(), oCheckpointMsg.filepath().c_str()); + + int ret = 0; + + if (oCheckpointMsg.flag() == CheckpointSendFileFlag_BEGIN) + { + ret = OnSendCheckpoint_Begin(oCheckpointMsg); + } + else if (oCheckpointMsg.flag() == CheckpointSendFileFlag_ING) + { + ret = OnSendCheckpoint_Ing(oCheckpointMsg); + } + else if (oCheckpointMsg.flag() == CheckpointSendFileFlag_END) + { + ret = OnSendCheckpoint_End(oCheckpointMsg); + } + + if (ret != 0) + { + PLGErr("[FAIL] reset checkpoint receiver and reset askforlearn"); + + m_oCheckpointReceiver.Reset(); + + Reset_AskforLearn_Noop(5000); + SendCheckpointAck(oCheckpointMsg.nodeid(), oCheckpointMsg.uuid(), oCheckpointMsg.sequence(), CheckpointSendFileAckFlag_Fail); + } + else + { + SendCheckpointAck(oCheckpointMsg.nodeid(), oCheckpointMsg.uuid(), oCheckpointMsg.sequence(), CheckpointSendFileAckFlag_OK); + Reset_AskforLearn_Noop(120000); + } +} + +int Learner :: SendCheckpointAck( + const nodeid_t iSendNodeID, + const uint64_t llUUID, + const uint64_t llSequence, + const int iFlag) +{ + CheckpointMsg oCheckpointMsg; + + oCheckpointMsg.set_msgtype(CheckpointMsgType_SendFile_Ack); + oCheckpointMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oCheckpointMsg.set_uuid(llUUID); + oCheckpointMsg.set_sequence(llSequence); + oCheckpointMsg.set_flag(iFlag); + + return SendMessage(iSendNodeID, oCheckpointMsg, Message_SendType_TCP); +} + +void Learner :: OnSendCheckpointAck(const CheckpointMsg & oCheckpointMsg) +{ + PLGHead("START flag %d", oCheckpointMsg.flag()); + + if (m_poCheckpointSender != nullptr && !m_poCheckpointSender->IsEnd()) + { + if (oCheckpointMsg.flag() == CheckpointSendFileAckFlag_OK) + { + m_poCheckpointSender->Ack(oCheckpointMsg.nodeid(), oCheckpointMsg.uuid(), oCheckpointMsg.sequence()); + } + else + { + m_poCheckpointSender->End(); + } + } +} + +CheckpointSender * Learner :: GetNewCheckpointSender(const nodeid_t iSendNodeID) +{ + if (m_poCheckpointSender != nullptr) + { + if (m_poCheckpointSender->IsEnd()) + { + m_poCheckpointSender->join(); + delete m_poCheckpointSender; + m_poCheckpointSender = nullptr; + } + } + + if (m_poCheckpointSender == nullptr) + { + m_poCheckpointSender = new CheckpointSender(iSendNodeID, m_poConfig, this, m_poSMFac, m_poCheckpointMgr); + return m_poCheckpointSender; + } + + return nullptr; +} + + +} + + diff --git a/src/algorithm/learner.h b/src/algorithm/learner.h new file mode 100644 index 000000000..bceda65ff --- /dev/null +++ b/src/algorithm/learner.h @@ -0,0 +1,218 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "base.h" +#include +#include "commdef.h" +#include "comm_include.h" +#include "paxos_log.h" +#include "ioloop.h" +#include "learner_sender.h" +#include "checkpoint_sender.h" +#include "checkpoint_receiver.h" + +namespace phxpaxos +{ + +class LearnerState +{ +public: + LearnerState(const Config * poConfig, const LogStorage * poLogStorage); + ~LearnerState(); + + void Init(); + + int LearnValue(const uint64_t llInstanceID, const BallotNumber & oLearnedBallot, + const std::string & sValue, const uint32_t iNewChecksum); + + void LearnValueWithoutWrite(const uint64_t llInstanceID, + const std::string & sValue, const uint32_t iNewChecksum); + + const std::string & GetLearnValue(); + + const bool GetIsLearned(); + + const uint32_t GetNewChecksum() const; + +private: + std::string m_sLearnedValue; + bool m_bIsLearned; + uint32_t m_iNewChecksum; + + Config * m_poConfig; + PaxosLog m_oPaxosLog; +}; + +/////////////////////////////////////////////////////// + + +class Acceptor; +class CheckpointMgr; +class SMFac; + +class Learner : public Base +{ +public: + Learner( + const Config * poConfig, + const MsgTransport * poMsgTransport, + const Instance * poInstance, + const Acceptor * poAcceptor, + const LogStorage * poLogStorage, + const IOLoop * poIOLoop, + const CheckpointMgr * poCheckpointMgr, + const SMFac * poSMFac); + virtual ~Learner(); + + void Init(); + + virtual void InitForNewPaxosInstance(); + + const bool IsLearned(); + + const std::string & GetLearnValue(); + + const uint32_t GetNewChecksum() const; + + void Stop(); + + //prepare learn + void AskforLearn(); + + void OnAskforLearn(const PaxosMsg & oPaxosMsg); + + void SendNowInstanceID(const uint64_t llInstanceID, const nodeid_t iSendNode); + + void OnSendNowInstanceID(const PaxosMsg & oPaxosMsg); + + void AskforCheckpoint(const nodeid_t iSendNodeID); + + void OnAskforCheckpoint(const PaxosMsg & oPaxosMsg); + + //comfirm learn + void ComfirmAskForLearn(const nodeid_t iSendNodeID); + + void OnComfirmAskForLearn(const PaxosMsg & oPaxosMsg); + + int SendLearnValue( + const nodeid_t iSendNodeID, + const uint64_t llLearnInstanceID, + const BallotNumber & oLearnedBallot, + const std::string & sLearnedValue, + const uint32_t iChecksum, + const bool bNeedAck = true); + + void OnSendLearnValue(const PaxosMsg & oPaxosMsg); + + void SendLearnValue_Ack(const nodeid_t iSendNodeID); + + void OnSendLearnValue_Ack(const PaxosMsg & oPaxosMsg); + + //success learn + virtual void ProposerSendSuccess( + const uint64_t llLearnInstanceID, + const uint64_t llProposalID); + + void OnProposerSendSuccess(const PaxosMsg & oPaxosMsg); + + void TransmitToFollower(); + + //learn noop + void AskforLearn_Noop(const bool bIsStart = false); + + void Reset_AskforLearn_Noop(const int iTimeout = ASKFORLEARN_NOOP_INTERVAL); + + //checkpoint logic + int SendCheckpointBegin( + const nodeid_t iSendNodeID, + const uint64_t llUUID, + const uint64_t llSequence, + const uint64_t llCheckpointInstanceID); + + int SendCheckpoint( + const nodeid_t iSendNodeID, + const uint64_t llUUID, + const uint64_t llSequence, + const uint64_t llCheckpointInstanceID, + const uint32_t iChecksum, + const std::string & sFilePath, + const int iSMID, + const uint64_t llOffset, + const std::string & sBuffer); + + int SendCheckpointEnd( + const nodeid_t iSendNodeID, + const uint64_t llUUID, + const uint64_t llSequence, + const uint64_t llCheckpointInstanceID); + + void OnSendCheckpoint(const CheckpointMsg & oCheckpointMsg); + + int SendCheckpointAck( + const nodeid_t iSendNodeID, + const uint64_t llUUID, + const uint64_t llSequence, + const int iFlag); + + void OnSendCheckpointAck(const CheckpointMsg & oCheckpointMsg); + + CheckpointSender * GetNewCheckpointSender(const nodeid_t iSendNodeID); + + /////////////////// + + const bool IsIMLatest(); + + const uint64_t GetSeenLatestInstanceID(); + + void SetSeenInstanceID(const uint64_t llInstanceID, const nodeid_t llFromNodeID); + +private: + int OnSendCheckpoint_Begin(const CheckpointMsg & oCheckpointMsg); + int OnSendCheckpoint_Ing(const CheckpointMsg & oCheckpointMsg); + int OnSendCheckpoint_End(const CheckpointMsg & oCheckpointMsg); + +private: + LearnerState m_oLearnerState; + + Acceptor * m_poAcceptor; + PaxosLog m_oPaxosLog; + + uint32_t m_iAskforlearn_noopTimerID; + IOLoop * m_poIOLoop; + + uint64_t m_llHighestSeenInstanceID; + nodeid_t m_iHighestSeenInstanceID_FromNodeID; + + bool m_bIsIMLearning; + LearnerSender m_oLearnerSender; + uint64_t m_llLastAckInstanceID; + + CheckpointMgr * m_poCheckpointMgr; + SMFac * m_poSMFac; + + CheckpointSender * m_poCheckpointSender; + CheckpointReceiver m_oCheckpointReceiver; +}; + +} + diff --git a/src/algorithm/learner_sender.cpp b/src/algorithm/learner_sender.cpp new file mode 100644 index 000000000..eeeca2f59 --- /dev/null +++ b/src/algorithm/learner_sender.cpp @@ -0,0 +1,263 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "learner_sender.h" +#include "learner.h" + +namespace phxpaxos +{ + +LearnerSender :: LearnerSender(Config * poConfig, Learner * poLearner, PaxosLog * poPaxosLog) + : m_poConfig(poConfig), m_poLearner(poLearner), m_poPaxosLog(poPaxosLog) +{ + m_bIsEnd = false; + m_bIsStart = false; + SendDone(); +} + +LearnerSender :: ~LearnerSender() +{ +} + +void LearnerSender :: Stop() +{ + m_bIsEnd = true; + if (m_bIsStart) + { + join(); + } +} + +void LearnerSender :: run() +{ + m_bIsStart = true; + + while (true) + { + WaitToSend(); + + if (m_bIsEnd) + { + PLGHead("Learner.Sender [END]"); + return; + } + + SendLearnedValue(m_llBeginInstanceID, m_iSendToNodeID); + + SendDone(); + } +} + +//////////////////////////////////////// + +void LearnerSender :: ReleshSending() +{ + m_llAbsLastSendTime = Time::GetTimestampMS(); +} + +const bool LearnerSender :: IsIMSending() +{ + if (!m_bIsIMSending) + { + return false; + } + + uint64_t llNowTime = Time::GetTimestampMS(); + uint64_t llPassTime = llNowTime > m_llAbsLastSendTime ? llNowTime - m_llAbsLastSendTime : 0; + + if ((int)llPassTime >= LearnerSender_PREPARE_TIMEOUT) + { + return false; + } + + return true; +} + +const bool LearnerSender :: CheckAck(const uint64_t llSendInstanceID) +{ + while (llSendInstanceID > m_llAckInstanceID + LearnerSender_ACK_LEAD) + { + uint64_t llNowTime = Time::GetTimestampMS(); + uint64_t llPassTime = llNowTime > m_llAbsLastAckTime ? llNowTime - m_llAbsLastAckTime : 0; + + if ((int)llPassTime >= LearnerSender_ACK_TIMEOUT) + { + BP->GetLearnerBP()->SenderAckTimeout(); + PLGErr("Ack timeout, last acktime %lu", m_llAbsLastAckTime); + return false; + } + + BP->GetLearnerBP()->SenderAckDelay(); + //PLGErr("Need sleep to slow down send speed, sendinstaceid %lu ackinstanceid %lu", + //llSendInstanceID, m_llAckInstanceID); + Time::MsSleep(50); + } + + return true; +} + +////////////////////////////////////////////////////////////////////////// + +const bool LearnerSender :: Prepare(const uint64_t llBeginInstanceID, const nodeid_t iSendToNodeID) +{ + m_oLock.Lock(); + + bool bPrepareRet = false; + if (!IsIMSending() && !m_bIsComfirmed) + { + bPrepareRet = true; + + m_bIsIMSending = true; + m_llAbsLastSendTime = m_llAbsLastAckTime = Time::GetTimestampMS(); + m_llBeginInstanceID = m_llAckInstanceID = llBeginInstanceID; + m_iSendToNodeID = iSendToNodeID; + } + + m_oLock.UnLock(); + + return bPrepareRet; +} + +const bool LearnerSender :: Comfirm(const uint64_t llBeginInstanceID, const nodeid_t iSendToNodeID) +{ + m_oLock.Lock(); + + bool bComfirmRet = false; + + if (IsIMSending() && (!m_bIsComfirmed)) + { + if (m_llBeginInstanceID == llBeginInstanceID && m_iSendToNodeID == iSendToNodeID) + { + bComfirmRet = true; + + m_bIsComfirmed = true; + m_oLock.Interupt(); + } + } + + m_oLock.UnLock(); + + return bComfirmRet; +} + +void LearnerSender :: Ack(const uint64_t llAckInstanceID, const nodeid_t iFromNodeID) +{ + m_oLock.Lock(); + + if (IsIMSending() && m_bIsComfirmed) + { + if (m_iSendToNodeID == iFromNodeID) + { + if (llAckInstanceID > m_llAckInstanceID) + { + m_llAckInstanceID = llAckInstanceID; + m_llAbsLastAckTime = Time::GetTimestampMS(); + } + } + } + + m_oLock.UnLock(); +} + +/////////////////////////////////////////////// + +void LearnerSender :: WaitToSend() +{ + m_oLock.Lock(); + while (!m_bIsComfirmed) + { + m_oLock.WaitTime(1000); + if (m_bIsEnd) + { + break; + } + } + m_oLock.UnLock(); +} + +void LearnerSender :: SendLearnedValue(const uint64_t llBeginInstanceID, const nodeid_t iSendToNodeID) +{ + PLGHead("BeginInstanceID %lu SendToNodeID %lu", llBeginInstanceID, iSendToNodeID); + + uint64_t llSendInstanceID = llBeginInstanceID; + int ret = 0; + + uint32_t iLastChecksum = 0; + + while (llSendInstanceID < m_poLearner->GetInstanceID()) + { + ret = SendOne(llSendInstanceID, iSendToNodeID, iLastChecksum); + if (ret != 0) + { + PLGErr("SendOne fail, SendInstanceID %lu SendToNodeID %lu ret %d", + llSendInstanceID, iSendToNodeID, ret); + return; + } + + if (!CheckAck(llSendInstanceID)) + { + return; + } + + llSendInstanceID++; + ReleshSending(); + } +} + +int LearnerSender :: SendOne(const uint64_t llSendInstanceID, const nodeid_t iSendToNodeID, uint32_t & iLastChecksum) +{ + BP->GetLearnerBP()->SenderSendOnePaxosLog(); + + AcceptorStateData oState; + int ret = m_poPaxosLog->ReadState(m_poConfig->GetMyGroupIdx(), llSendInstanceID, oState); + if (ret != 0) + { + return ret; + } + + BallotNumber oBallot(oState.acceptedid(), oState.acceptednodeid()); + + ret = m_poLearner->SendLearnValue(iSendToNodeID, llSendInstanceID, oBallot, oState.acceptedvalue(), iLastChecksum); + + iLastChecksum = oState.checksum(); + + return ret; +} + +void LearnerSender :: SendDone() +{ + m_oLock.Lock(); + + m_bIsIMSending = false; + m_bIsComfirmed = false; + m_llBeginInstanceID = (uint64_t)-1; + m_iSendToNodeID = nullnode; + m_llAbsLastSendTime = 0; + + m_llAckInstanceID = 0; + m_llAbsLastAckTime = 0; + + m_oLock.UnLock(); +} + + +} + diff --git a/src/algorithm/learner_sender.h b/src/algorithm/learner_sender.h new file mode 100644 index 000000000..434e7c040 --- /dev/null +++ b/src/algorithm/learner_sender.h @@ -0,0 +1,87 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "utils_include.h" +#include "comm_include.h" +#include "config_include.h" +#include "paxos_log.h" + +namespace phxpaxos +{ + +class Learner; + +class LearnerSender : public Thread +{ +public: + LearnerSender(Config * poConfig, Learner * poLearner, PaxosLog * poPaxosLog); + ~LearnerSender(); + + void run(); + + void Stop(); + +public: + const bool Prepare(const uint64_t llBeginInstanceID, const nodeid_t iSendToNodeID); + + const bool Comfirm(const uint64_t llBeginInstanceID, const nodeid_t iSendToNodeID); + + void Ack(const uint64_t llAckInstanceID, const nodeid_t iFromNodeID); + +private: + void WaitToSend(); + + void SendLearnedValue(const uint64_t llBeginInstanceID, const nodeid_t iSendToNodeID); + + int SendOne(const uint64_t llSendInstanceID, const nodeid_t iSendToNodeID, uint32_t & iLastChecksum); + + void SendDone(); + + const bool IsIMSending(); + + void ReleshSending(); + + const bool CheckAck(const uint64_t llSendInstanceID); + +private: + Config * m_poConfig; + Learner * m_poLearner; + PaxosLog * m_poPaxosLog; + SerialLock m_oLock; + + bool m_bIsIMSending; + uint64_t m_llAbsLastSendTime; + + uint64_t m_llBeginInstanceID; + nodeid_t m_iSendToNodeID; + + bool m_bIsComfirmed; + + uint64_t m_llAckInstanceID; + uint64_t m_llAbsLastAckTime; + + bool m_bIsEnd; + bool m_bIsStart; +}; + +} diff --git a/src/algorithm/msg_counter.cpp b/src/algorithm/msg_counter.cpp new file mode 100644 index 000000000..64e58924f --- /dev/null +++ b/src/algorithm/msg_counter.cpp @@ -0,0 +1,86 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "msg_counter.h" +#include +#include "config_include.h" + +namespace phxpaxos +{ + +MsgCounter :: MsgCounter(const Config * poConfig) +{ + m_poConfig = (Config *)poConfig; + StartNewRound(); +} + +MsgCounter :: ~MsgCounter() +{ +} + +void MsgCounter :: StartNewRound() +{ + m_setReceiveMsgNodeID.clear(); + m_setRejectMsgNodeID.clear(); + m_setPromiseOrAcceptMsgNodeID.clear(); +} + +void MsgCounter :: AddReceive(const nodeid_t iNodeID) +{ + if (m_setReceiveMsgNodeID.find(iNodeID) == m_setReceiveMsgNodeID.end()) + { + m_setReceiveMsgNodeID.insert(iNodeID); + } +} + +void MsgCounter :: AddReject(const nodeid_t iNodeID) +{ + if (m_setRejectMsgNodeID.find(iNodeID) == m_setRejectMsgNodeID.end()) + { + m_setRejectMsgNodeID.insert(iNodeID); + } +} + +void MsgCounter :: AddPromiseOrAccept(const nodeid_t iNodeID) +{ + if (m_setPromiseOrAcceptMsgNodeID.find(iNodeID) == m_setPromiseOrAcceptMsgNodeID.end()) + { + m_setPromiseOrAcceptMsgNodeID.insert(iNodeID); + } +} + +bool MsgCounter :: IsPassedOnThisRound() +{ + return (int)m_setPromiseOrAcceptMsgNodeID.size() >= m_poConfig->GetMajorityCount(); +} + +bool MsgCounter :: IsRejectedOnThisRound() +{ + return (int)m_setRejectMsgNodeID.size() >= m_poConfig->GetMajorityCount(); +} + +bool MsgCounter :: IsAllReceiveOnThisRound() +{ + return (int)m_setReceiveMsgNodeID.size() == m_poConfig->GetNodeCount(); +} + +} + diff --git a/src/algorithm/msg_counter.h b/src/algorithm/msg_counter.h new file mode 100644 index 000000000..c282a13f9 --- /dev/null +++ b/src/algorithm/msg_counter.h @@ -0,0 +1,58 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include "commdef.h" + +namespace phxpaxos +{ + +class Config; +class PaxosLog; + +class MsgCounter +{ +public: + MsgCounter(const Config * poConfig); + ~MsgCounter(); + + void AddReceive(const nodeid_t iNodeID); + void AddReject(const nodeid_t iNodeID); + void AddPromiseOrAccept(const nodeid_t iNodeID); + + bool IsPassedOnThisRound(); + bool IsRejectedOnThisRound(); + bool IsAllReceiveOnThisRound(); + + void StartNewRound(); + +public: + Config * m_poConfig; + + std::set m_setReceiveMsgNodeID; + std::set m_setRejectMsgNodeID; + std::set m_setPromiseOrAcceptMsgNodeID; +}; + +} diff --git a/src/algorithm/proposer.cpp b/src/algorithm/proposer.cpp new file mode 100644 index 000000000..fed862f1e --- /dev/null +++ b/src/algorithm/proposer.cpp @@ -0,0 +1,502 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "proposer.h" +#include "learner.h" +#include "phxpaxos/sm.h" +#include "instance.h" + +namespace phxpaxos +{ + +ProposerState :: ProposerState(const Config * poConfig) +{ + m_poConfig = (Config *)poConfig; + m_llProposalID = 1; + Init(); +} + +ProposerState :: ~ProposerState() +{ +} + +void ProposerState :: Init() +{ + m_llHighestOtherProposalID = 0; + m_sValue.clear(); +} + +void ProposerState :: SetStartProposalID(const uint64_t llProposalID) +{ + m_llProposalID = llProposalID; +} + +void ProposerState :: NewPrepare() +{ + PLGHead("START ProposalID %lu HighestOther %lu MyNodeID %lu", + m_llProposalID, m_llHighestOtherProposalID, m_poConfig->GetMyNodeID()); + + uint64_t llMaxProposalID = + m_llProposalID > m_llHighestOtherProposalID ? m_llProposalID : m_llHighestOtherProposalID; + + m_llProposalID = llMaxProposalID + 1; + + PLGHead("END New.ProposalID %lu", m_llProposalID); + +} + +void ProposerState :: AddPreAcceptValue( + const BallotNumber & oOtherPreAcceptBallot, + const std::string & sOtherPreAcceptValue) +{ + PLGDebug("OtherPreAcceptID %lu OtherPreAcceptNodeID %lu HighestOtherPreAcceptID %lu " + "HighestOtherPreAcceptNodeID %lu OtherPreAcceptValue %zu", + oOtherPreAcceptBallot.m_llProposalID, oOtherPreAcceptBallot.m_llNodeID, + m_oHighestOtherPreAcceptBallot.m_llProposalID, m_oHighestOtherPreAcceptBallot.m_llNodeID, + sOtherPreAcceptValue.size()); + + if (oOtherPreAcceptBallot.isnull()) + { + return; + } + + if (oOtherPreAcceptBallot > m_oHighestOtherPreAcceptBallot) + { + m_oHighestOtherPreAcceptBallot = oOtherPreAcceptBallot; + m_sValue = sOtherPreAcceptValue; + } +} + +const uint64_t ProposerState :: GetProposalID() +{ + return m_llProposalID; +} + +const std::string & ProposerState :: GetValue() +{ + return m_sValue; +} + +void ProposerState :: SetValue(const std::string & sValue) +{ + m_sValue = sValue; +} + +void ProposerState :: SetOtherProposalID(const uint64_t llOtherProposalID) +{ + if (llOtherProposalID > m_llHighestOtherProposalID) + { + m_llHighestOtherProposalID = llOtherProposalID; + } +} + +void ProposerState :: ResetHighestOtherPreAcceptBallot() +{ + m_oHighestOtherPreAcceptBallot.reset(); +} + +//////////////////////////////////////////////////////////////// + +Proposer :: Proposer( + const Config * poConfig, + const MsgTransport * poMsgTransport, + const Instance * poInstance, + const Learner * poLearner, + const IOLoop * poIOLoop) + : Base(poConfig, poMsgTransport, poInstance), m_oProposerState(poConfig), m_oMsgCounter(poConfig) +{ + m_poLearner = (Learner *)poLearner; + m_poIOLoop = (IOLoop *)poIOLoop; + + m_bIsPreparing = false; + m_bIsAccepting = false; + + m_bCanSkipPrepare = false; + + InitForNewPaxosInstance(); + + m_iPrepareTimerID = 0; + m_iAcceptTimerID = 0; + m_llTimeoutInstanceID = 0; + + m_iLastPrepareTimeoutMs = m_poConfig->GetPrepareTimeoutMs(); + m_iLastAcceptTimeoutMs = m_poConfig->GetAcceptTimeoutMs(); + + m_bWasRejectBySomeone = false; +} + +Proposer :: ~Proposer() +{ +} + +void Proposer :: SetStartProposalID(const uint64_t llProposalID) +{ + m_oProposerState.SetStartProposalID(llProposalID); +} + +void Proposer :: InitForNewPaxosInstance() +{ + m_oMsgCounter.StartNewRound(); + m_oProposerState.Init(); + + ExitPrepare(); + ExitAccept(); +} + +bool Proposer :: IsWorking() +{ + return m_bIsPreparing || m_bIsAccepting; +} + +int Proposer :: NewValue(const std::string & sValue) +{ + BP->GetProposerBP()->NewProposal(sValue); + + m_oProposerState.SetValue(sValue); + + m_iLastPrepareTimeoutMs = START_PREPARE_TIMEOUTMS; + m_iLastAcceptTimeoutMs = START_ACCEPT_TIMEOUTMS; + + if (m_bCanSkipPrepare && !m_bWasRejectBySomeone) + { + BP->GetProposerBP()->NewProposalSkipPrepare(); + + PLGHead("skip prepare, directly start accept"); + Accept(); + } + else + { + //if not reject by someone, no need to increase ballot + Prepare(m_bWasRejectBySomeone); + } + + return 0; +} + +void Proposer :: ExitPrepare() +{ + if (m_bIsPreparing) + { + m_bIsPreparing = false; + + m_poIOLoop->RemoveTimer(m_iPrepareTimerID); + } +} + +void Proposer :: ExitAccept() +{ + if (m_bIsAccepting) + { + m_bIsAccepting = false; + + m_poIOLoop->RemoveTimer(m_iAcceptTimerID); + } +} + +void Proposer :: AddPrepareTimer(const int iTimeoutMs) +{ + if (m_iPrepareTimerID > 0) + { + m_poIOLoop->RemoveTimer(m_iPrepareTimerID); + } + + if (iTimeoutMs > 0) + { + m_poIOLoop->AddTimer( + iTimeoutMs, + Timer_Proposer_Prepare_Timeout, + m_iPrepareTimerID); + return; + } + + m_poIOLoop->AddTimer( + m_iLastPrepareTimeoutMs, + Timer_Proposer_Prepare_Timeout, + m_iPrepareTimerID); + + m_llTimeoutInstanceID = GetInstanceID(); + + PLGHead("timeoutms %d", m_iLastPrepareTimeoutMs); + + m_iLastPrepareTimeoutMs *= 2; + if (m_iLastPrepareTimeoutMs > MAX_PREPARE_TIMEOUTMS) + { + m_iLastPrepareTimeoutMs = MAX_PREPARE_TIMEOUTMS; + } +} + +void Proposer :: AddAcceptTimer(const int iTimeoutMs) +{ + if (m_iAcceptTimerID > 0) + { + m_poIOLoop->RemoveTimer(m_iAcceptTimerID); + } + + if (iTimeoutMs > 0) + { + m_poIOLoop->AddTimer( + iTimeoutMs, + Timer_Proposer_Accept_Timeout, + m_iAcceptTimerID); + return; + } + + m_poIOLoop->AddTimer( + m_iLastAcceptTimeoutMs, + Timer_Proposer_Accept_Timeout, + m_iAcceptTimerID); + + m_llTimeoutInstanceID = GetInstanceID(); + + PLGHead("timeoutms %d", m_iLastPrepareTimeoutMs); + + m_iLastAcceptTimeoutMs *= 2; + if (m_iLastAcceptTimeoutMs > MAX_ACCEPT_TIMEOUTMS) + { + m_iLastAcceptTimeoutMs = MAX_ACCEPT_TIMEOUTMS; + } +} + +void Proposer :: Prepare(const bool bNeedNewBallot) +{ + PLGHead("START Now.InstanceID %lu MyNodeID %lu State.ProposalID %lu State.ValueLen %zu", + GetInstanceID(), m_poConfig->GetMyNodeID(), m_oProposerState.GetProposalID(), + m_oProposerState.GetValue().size()); + + BP->GetProposerBP()->Prepare(); + m_oTimeStat.Point(); + + ExitAccept(); + m_bIsPreparing = true; + m_bCanSkipPrepare = false; + m_bWasRejectBySomeone = false; + + m_oProposerState.ResetHighestOtherPreAcceptBallot(); + if (bNeedNewBallot) + { + m_oProposerState.NewPrepare(); + } + + PaxosMsg oPaxosMsg; + oPaxosMsg.set_msgtype(MsgType_PaxosPrepare); + oPaxosMsg.set_instanceid(GetInstanceID()); + oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oPaxosMsg.set_proposalid(m_oProposerState.GetProposalID()); + + m_oMsgCounter.StartNewRound(); + + AddPrepareTimer(); + + PLGHead("END OK"); + + BroadcastMessage(oPaxosMsg); +} + +void Proposer :: OnPrepareReply(const PaxosMsg & oPaxosMsg) +{ + PLGHead("START Msg.ProposalID %lu State.ProposalID %lu Msg.from_nodeid %lu RejectByPromiseID %lu", + oPaxosMsg.proposalid(), m_oProposerState.GetProposalID(), + oPaxosMsg.nodeid(), oPaxosMsg.rejectbypromiseid()); + + BP->GetProposerBP()->OnPrepareReply(); + + if (!m_bIsPreparing) + { + BP->GetProposerBP()->OnPrepareReplyButNotPreparing(); + PLGErr("Not preparing, skip this msg"); + return; + } + + if (oPaxosMsg.proposalid() != m_oProposerState.GetProposalID()) + { + BP->GetProposerBP()->OnPrepareReplyNotSameProposalIDMsg(); + PLGErr("ProposalID not same, skip this msg"); + return; + } + + m_oMsgCounter.AddReceive(oPaxosMsg.nodeid()); + + if (oPaxosMsg.rejectbypromiseid() == 0) + { + BallotNumber oBallot(oPaxosMsg.preacceptid(), oPaxosMsg.preacceptnodeid()); + + PLGDebug("[Promise] PreAcceptedID %lu PreAcceptedNodeID %lu ValueSize %zu", + oPaxosMsg.preacceptid(), oPaxosMsg.preacceptnodeid(), oPaxosMsg.value().size()); + + m_oMsgCounter.AddPromiseOrAccept(oPaxosMsg.nodeid()); + + m_oProposerState.AddPreAcceptValue(oBallot, oPaxosMsg.value()); + } + else + { + PLGDebug("[Reject] RejectByPromiseID %lu", oPaxosMsg.rejectbypromiseid()); + + m_oMsgCounter.AddReject(oPaxosMsg.nodeid()); + + m_bWasRejectBySomeone = true; + + m_oProposerState.SetOtherProposalID(oPaxosMsg.rejectbypromiseid()); + } + + if (m_oMsgCounter.IsPassedOnThisRound()) + { + int iUseTimeMs = m_oTimeStat.Point(); + BP->GetProposerBP()->PreparePass(iUseTimeMs); + PLGImp("[Pass] start accept, usetime %dms", iUseTimeMs); + m_bCanSkipPrepare = true; + Accept(); + } + else if (m_oMsgCounter.IsRejectedOnThisRound() + || m_oMsgCounter.IsAllReceiveOnThisRound()) + { + BP->GetProposerBP()->PrepareNotPass(); + PLGImp("[Not Pass] wait 30ms and restart prepare"); + AddPrepareTimer(30); + } + + PLGHead("END"); +} + +void Proposer :: Accept() +{ + PLGHead("START ProposalID %lu ValueSize %zu ValueLen %zu", + m_oProposerState.GetProposalID(), m_oProposerState.GetValue().size(), m_oProposerState.GetValue().size()); + + BP->GetProposerBP()->Accept(); + m_oTimeStat.Point(); + + ExitPrepare(); + m_bIsAccepting = true; + + PaxosMsg oPaxosMsg; + oPaxosMsg.set_msgtype(MsgType_PaxosAccept); + oPaxosMsg.set_instanceid(GetInstanceID()); + oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID()); + oPaxosMsg.set_proposalid(m_oProposerState.GetProposalID()); + oPaxosMsg.set_value(m_oProposerState.GetValue()); + oPaxosMsg.set_lastchecksum(GetLastChecksum()); + + m_oMsgCounter.StartNewRound(); + + AddAcceptTimer(); + + PLGHead("END"); + + BroadcastMessage(oPaxosMsg, BroadcastMessage_Type_RunSelf_Final); +} + +void Proposer :: OnAcceptReply(const PaxosMsg & oPaxosMsg) +{ + PLGHead("START Msg.ProposalID %lu State.ProposalID %lu Msg.from_nodeid %lu RejectByPromiseID %lu", + oPaxosMsg.proposalid(), m_oProposerState.GetProposalID(), + oPaxosMsg.nodeid(), oPaxosMsg.rejectbypromiseid()); + + BP->GetProposerBP()->OnAcceptReply(); + + if (!m_bIsAccepting) + { + PLGErr("Not proposing, skip this msg"); + BP->GetProposerBP()->OnAcceptReplyButNotAccepting(); + return; + } + + if (oPaxosMsg.proposalid() != m_oProposerState.GetProposalID()) + { + BP->GetProposerBP()->OnAcceptReplyNotSameProposalIDMsg(); + PLGErr("ProposalID not same, skip this msg"); + return; + } + + m_oMsgCounter.AddReceive(oPaxosMsg.nodeid()); + + if (oPaxosMsg.rejectbypromiseid() == 0) + { + PLGDebug("[Accept]"); + m_oMsgCounter.AddPromiseOrAccept(oPaxosMsg.nodeid()); + } + else + { + PLGDebug("[Reject]"); + m_oMsgCounter.AddReject(oPaxosMsg.nodeid()); + + m_bWasRejectBySomeone = true; + + m_oProposerState.SetOtherProposalID(oPaxosMsg.rejectbypromiseid()); + } + + if (m_oMsgCounter.IsPassedOnThisRound()) + { + int iUseTimeMs = m_oTimeStat.Point(); + BP->GetProposerBP()->AcceptPass(iUseTimeMs); + PLGImp("[Pass] Start send learn, usetime %dms", iUseTimeMs); + ExitAccept(); + m_poLearner->ProposerSendSuccess(GetInstanceID(), m_oProposerState.GetProposalID()); + } + else if (m_oMsgCounter.IsRejectedOnThisRound() + || m_oMsgCounter.IsAllReceiveOnThisRound()) + { + BP->GetProposerBP()->AcceptNotPass(); + PLGImp("[Not pass] wait 30ms and Restart prepare"); + AddAcceptTimer(30); + } + + PLGHead("END"); +} + +void Proposer :: OnPrepareTimeout() +{ + PLGHead("OK"); + + if (GetInstanceID() != m_llTimeoutInstanceID) + { + PLGErr("TimeoutInstanceID %lu not same to NowInstanceID %lu, skip", + m_llTimeoutInstanceID, GetInstanceID()); + return; + } + + BP->GetProposerBP()->PrepareTimeout(); + + Prepare(m_bWasRejectBySomeone); +} + +void Proposer :: OnAcceptTimeout() +{ + PLGHead("OK"); + + if (GetInstanceID() != m_llTimeoutInstanceID) + { + PLGErr("TimeoutInstanceID %lu not same to NowInstanceID %lu, skip", + m_llTimeoutInstanceID, GetInstanceID()); + return; + } + + BP->GetProposerBP()->AcceptTimeout(); + + Prepare(m_bWasRejectBySomeone); +} + +void Proposer :: CancelSkipPrepare() +{ + m_bCanSkipPrepare = false; +} + +} + diff --git a/src/algorithm/proposer.h b/src/algorithm/proposer.h new file mode 100644 index 000000000..df54118fc --- /dev/null +++ b/src/algorithm/proposer.h @@ -0,0 +1,142 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "base.h" +#include +#include "ioloop.h" +#include "msg_counter.h" + +namespace phxpaxos +{ + +class ProposerState +{ +public: + ProposerState(const Config * poConfig); + ~ProposerState(); + + void Init(); + + void SetStartProposalID(const uint64_t llProposalID); + + void NewPrepare(); + + void AddPreAcceptValue(const BallotNumber & oOtherPreAcceptBallot, const std::string & sOtherPreAcceptValue); + + ///////////////////////// + + const uint64_t GetProposalID(); + + const std::string & GetValue(); + + void SetValue(const std::string & sValue); + + void SetOtherProposalID(const uint64_t llOtherProposalID); + + void ResetHighestOtherPreAcceptBallot(); + +public: + uint64_t m_llProposalID; + uint64_t m_llHighestOtherProposalID; + std::string m_sValue; + + BallotNumber m_oHighestOtherPreAcceptBallot; + + Config * m_poConfig; +}; + +////////////////////////////////////////////////// + +class Learner; + +class Proposer : public Base +{ +public: + Proposer( + const Config * poConfig, + const MsgTransport * poMsgTransport, + const Instance * poInstance, + const Learner * poLearner, + const IOLoop * poIOLoop); + ~Proposer(); + + void SetStartProposalID(const uint64_t llProposalID); + + virtual void InitForNewPaxosInstance(); + + int NewValue(const std::string & sValue); + + bool IsWorking(); + + ///////////////////////////// + + void Prepare(const bool bNeedNewBallot = true); + + void OnPrepareReply(const PaxosMsg & oPaxosMsg); + + void Accept(); + + void OnAcceptReply(const PaxosMsg & oPaxosMsg); + + void OnPrepareTimeout(); + + void OnAcceptTimeout(); + + void ExitPrepare(); + + void ExitAccept(); + + void CancelSkipPrepare(); + + ///////////////////////////// + + void AddPrepareTimer(const int iTimeoutMs = 0); + + void AddAcceptTimer(const int iTimeoutMs = 0); + +public: + ProposerState m_oProposerState; + MsgCounter m_oMsgCounter; + Learner * m_poLearner; + + bool m_bIsPreparing; + bool m_bIsAccepting; + + bool m_bIMLeader; + + IOLoop * m_poIOLoop; + + uint32_t m_iPrepareTimerID; + int m_iLastPrepareTimeoutMs; + uint32_t m_iAcceptTimerID; + int m_iLastAcceptTimeoutMs; + uint64_t m_llTimeoutInstanceID; + + bool m_bCanSkipPrepare; + + bool m_bWasRejectBySomeone; + + TimeStat m_oTimeStat; +}; + +} diff --git a/src/benchmark/HOW_TO_BENCH b/src/benchmark/HOW_TO_BENCH new file mode 100644 index 000000000..cb2d77e4f --- /dev/null +++ b/src/benchmark/HOW_TO_BENCH @@ -0,0 +1,35 @@ +1. make. +2. run phx_paxos_bench on different machine. +3. run phx_paxos_bench and appoint bench. + +#args explanation: +phx_paxos_bench have 4 args like " " + +Myip:myport means running machine's ip/port. +The second arg is all running machine's ip/port list. +Third arg, is to appoint bench or not. Only one machine need to appoint bench(means fill this arg as 'y'). +Last arg, set how many paxos group you want to running on one machine. different paxos group count will have different benchmark. + +#sample command. + +Now grant we have three machine. (10.10.10.10:11111), (10.10.10.11:11111), (10.10.10.12:11111). +You must change this ip/port list to your real environment first. +And now I want to get 20 paxos group count's benchmark. +We do this: + +#first run below command on first machine. +./phxecho 10.10.10.10:11111 10.10.10.10:11111,10.10.10.11:11111,10.10.10.12:11111 n 20 + +#second run below command on second machine. +./phxecho 10.10.10.10:11112 10.10.10.10:11111,10.10.10.11:11111,10.10.10.12:11111 n 20 + +#last run below command on third machine. Notice that need to appoint bench on args. +./phxecho 10.10.10.12:11112 10.10.10.10:11111,10.10.10.11:11111,10.10.10.12:11111 y 20 + +Wait a minutes. then you will get the benchmark(qps) on standard output. + +##Notice +Every times you run phx_paxos_bench, it will generate a dir names logpath_myip_myport on current dir. +This dir is use to save paxos data on disk. + +So if you want to reset all things before bench, just rm this dirs on every machine. diff --git a/src/benchmark/Makefile.define b/src/benchmark/Makefile.define new file mode 100644 index 000000000..156dea26e --- /dev/null +++ b/src/benchmark/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=phx_paxos_bench + +PHX_PAXOS_BENCH_OBJ=bench_sm.o bench_server.o bench_main.o + +PHX_PAXOS_BENCH_LIB=src/utils:utils src/algorithm:algorithm + +PHX_PAXOS_BENCH_SYS_LIB=$(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread $(PROTOBUF_LIB_PATH)/libprotobuf.a + +PHX_PAXOS_BENCH_INCS=$(SRC_BASE_PATH)/src/benchmark $(PHXPAXOS_INCLUDE_PATH) $(LEVELDB_INCLUDE_PATH) $(PROTOBUF_INCLUDE_PATH) + +PHX_PAXOS_BENCH_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/benchmark/bench_main.cpp b/src/benchmark/bench_main.cpp new file mode 100644 index 000000000..1bae5a527 --- /dev/null +++ b/src/benchmark/bench_main.cpp @@ -0,0 +1,265 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "bench_server.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "phxpaxos/options.h" +#include "utils_include.h" + +using namespace bench; +using namespace phxpaxos; +using namespace std; + +int parse_ipport(const char * pcStr, NodeInfo & oNodeInfo) +{ + char sIP[32] = {0}; + int iPort = -1; + + int count = sscanf(pcStr, "%[^':']:%d", sIP, &iPort); + if (count != 2) + { + return -1; + } + + oNodeInfo.SetIPPort(sIP, iPort); + + return 0; +} + +int parse_ipport_list(const char * pcStr, NodeInfoList & vecNodeInfoList) +{ + string sTmpStr; + int iStrLen = strlen(pcStr); + + for (int i = 0; i < iStrLen; i++) + { + if (pcStr[i] == ',' || i == iStrLen - 1) + { + if (i == iStrLen - 1 && pcStr[i] != ',') + { + sTmpStr += pcStr[i]; + } + + NodeInfo oNodeInfo; + int ret = parse_ipport(sTmpStr.c_str(), oNodeInfo); + if (ret != 0) + { + return ret; + } + + vecNodeInfoList.push_back(oNodeInfo); + + sTmpStr = ""; + } + else + { + sTmpStr += pcStr[i]; + } + } + + return 0; +} + +const uint64_t GetTimestampMS() +{ + uint64_t llNow; + struct timeval tv; + + gettimeofday(&tv, NULL); + + llNow = tv.tv_sec; + llNow *= 1000; + llNow += tv.tv_usec / 1000; + + return llNow; +} + +void RandValue(const int iSize, string & sValue) +{ + sValue = ""; + int iRealSize = rand() % iSize + iSize / 2; + + for (int i = 0; i < iRealSize; i++) + { + sValue += 'a'; + } +} + +class BenchClient : public phxpaxos::Thread +{ +public: + BenchClient(BenchServer * poBenchServer, const int iWriteCount, const int iAvgValueSize) : + m_poBenchServer(poBenchServer), m_iWriteCount(iWriteCount), m_iAvgValueSize(iAvgValueSize) { } + + ~BenchClient() { join(); } + + void run() + { + string sValue; + for (int i = 0; i < m_iWriteCount; i++) + { + RandValue(m_iAvgValueSize, sValue); + int ret = m_poBenchServer->Write(sValue); + if (ret != 0) + { + printf("bench fail\n"); + return; + } + } + } + +private: + BenchServer * m_poBenchServer; + int m_iWriteCount; + int m_iAvgValueSize; +}; + +void Bench_SmallData(BenchServer & oBenchServer) +{ + uint64_t llBeginTimeMs = GetTimestampMS(); + + const int iWriteCount = 1000; + const int iConcurrentCount = 100; + int iAvgValueSize = 100; + + vector vecBenchClient; + for (int i = 0; i < iConcurrentCount; i++) + { + BenchClient * poBenchClient = new BenchClient(&oBenchServer, iWriteCount, iAvgValueSize); + poBenchClient->start(); + vecBenchClient.push_back(poBenchClient); + } + + for (int i = 0; i < iConcurrentCount; i++) + { + delete vecBenchClient[i]; + } + + uint64_t llEndTimeMs = GetTimestampMS(); + int iRunTimeMs = llEndTimeMs - llBeginTimeMs; + int qps = (uint64_t)iWriteCount * iConcurrentCount * 1000 / iRunTimeMs; + + printf("avg value size %d qps %d\n", iAvgValueSize, qps); +} + +void Bench_LargeData(BenchServer & oBenchServer) +{ + uint64_t llBeginTimeMs = GetTimestampMS(); + + const int iWriteCount = 100; + const int iConcurrentCount = 100; + int iAvgValueSize = 100 * 1000; + + vector vecBenchClient; + for (int i = 0; i < iConcurrentCount; i++) + { + BenchClient * poBenchClient = new BenchClient(&oBenchServer, iWriteCount, iAvgValueSize); + poBenchClient->start(); + vecBenchClient.push_back(poBenchClient); + } + + for (int i = 0; i < iConcurrentCount; i++) + { + delete vecBenchClient[i]; + } + + uint64_t llEndTimeMs = GetTimestampMS(); + int iRunTimeMs = llEndTimeMs - llBeginTimeMs; + int qps = (uint64_t)iWriteCount * iConcurrentCount * 1000 / iRunTimeMs; + + printf("avg value size %d qps %d\n", iAvgValueSize, qps); +} + +void Bench(BenchServer & oBenchServer) +{ + int ret = oBenchServer.ReadyBench(); + if (ret != 0) + { + printf("bench start fail\n"); + return; + } + + printf("start bench small data\n"); + Bench_SmallData(oBenchServer); + printf("start bench large data\n"); + Bench_LargeData(oBenchServer); +} + +int main(int argc, char ** argv) +{ + if (argc < 4) + { + printf("%s " + " \n", argv[0]); + return -1; + } + + NodeInfo oMyNode; + if (parse_ipport(argv[1], oMyNode) != 0) + { + printf("parse myip:myport fail\n"); + return -1; + } + + NodeInfoList vecNodeInfoList; + if (parse_ipport_list(argv[2], vecNodeInfoList) != 0) + { + printf("parse ip/port list fail\n"); + return -1; + } + + int iGroupCount = 1; + if (argc >= 5) + { + iGroupCount = atoi(argv[4]); + } + + BenchServer oBenchServer(iGroupCount, oMyNode, vecNodeInfoList); + int ret = oBenchServer.RunPaxos(); + if (ret != 0) + { + printf("run paxos fail\n"); + return -1; + } + + string sStartBench = argv[3]; + if (sStartBench == "y") + { + Bench(oBenchServer); + } + else + { + //run damon + while(true) sleep(1); + } + + return 0; +} + diff --git a/src/benchmark/bench_server.cpp b/src/benchmark/bench_server.cpp new file mode 100644 index 000000000..7096ee238 --- /dev/null +++ b/src/benchmark/bench_server.cpp @@ -0,0 +1,157 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "bench_server.h" +#include +#include +#include +#include +#include +#include + +using namespace phxpaxos; +using namespace std; + +namespace bench +{ + +BenchServer :: BenchServer(const int iGroupCount, const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList) + : m_oMyNode(oMyNode), m_vecNodeList(vecNodeList), m_poPaxosNode(nullptr) +{ + m_iGroupCount = iGroupCount; + + for (int iGroupIdx = 0; iGroupIdx < m_iGroupCount; iGroupIdx++) + { + BenchSM * poBenchSM = new BenchSM(oMyNode.GetNodeID(), iGroupIdx); + assert(poBenchSM != nullptr); + m_vecSMList.push_back(poBenchSM); + } +} + +BenchServer :: ~BenchServer() +{ + delete m_poPaxosNode; + + for (auto & poBenchSM : m_vecSMList) + { + delete poBenchSM; + } +} + +int BenchServer :: MakeLogStoragePath(std::string & sLogStoragePath) +{ + char sTmp[128] = {0}; + snprintf(sTmp, sizeof(sTmp), "./logpath_%s_%d", m_oMyNode.GetIP().c_str(), m_oMyNode.GetPort()); + + sLogStoragePath = string(sTmp); + + if (access(sLogStoragePath.c_str(), F_OK) == -1) + { + if (mkdir(sLogStoragePath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) + { + printf("Create dir fail, path %s\n", sLogStoragePath.c_str()); + return -1; + } + } + + return 0; +} + +int BenchServer :: RunPaxos() +{ + Options oOptions; + + int ret = MakeLogStoragePath(oOptions.sLogStoragePath); + if (ret != 0) + { + return ret; + } + + //this groupcount means run paxos group count. + //every paxos group is independent, there are no any communicate between any 2 paxos group. + oOptions.iGroupCount = m_iGroupCount; + + oOptions.oMyNode = m_oMyNode; + oOptions.vecNodeInfoList = m_vecNodeList; + + //different paxos group can have different state machine. + for (auto & poBenchSM : m_vecSMList) + { + GroupSMInfo oSMInfo; + oSMInfo.iGroupIdx = poBenchSM->GetGroupIdx(); + //one paxos group can have multi state machine. + oSMInfo.vecSMList.push_back(poBenchSM); + + oOptions.vecGroupSMInfoList.push_back(oSMInfo); + } + + ret = Node::RunNode(oOptions, m_poPaxosNode); + if (ret != 0) + { + printf("run paxos fail, ret %d\n", ret); + return ret; + } + + printf("run paxos ok\n"); + return 0; +} + +int BenchServer :: ReadyBench() +{ + int ret = 0; + for (int i = 0; i < m_iGroupCount; i++) + { + ret = Write(i, "start bence"); + if (ret != 0) + { + return ret; + } + } + + return 0; +} + +int BenchServer :: Write(const std::string & sBenceValue) +{ + int iGroupIdx = rand() % m_iGroupCount; + return Write(iGroupIdx, sBenceValue); +} + +int BenchServer :: Write(const int iGroupIdx, const std::string & sBenceValue) +{ + + SMCtx oCtx; + //smid must same to BenchSM.SMID(). + oCtx.m_iSMID = 1; + oCtx.m_pCtx = nullptr; + + uint64_t llInstanceID = 0; + int ret = m_poPaxosNode->Propose(iGroupIdx, sBenceValue, llInstanceID, &oCtx); + if (ret != 0) + { + return ret; + } + + return 0; +} + +} + diff --git a/src/benchmark/bench_server.h b/src/benchmark/bench_server.h new file mode 100644 index 000000000..8fcaef838 --- /dev/null +++ b/src/benchmark/bench_server.h @@ -0,0 +1,61 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/node.h" +#include "bench_sm.h" +#include +#include + +namespace bench +{ + +class BenchServer +{ +public: + BenchServer(const int iGroupCount, const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList); + ~BenchServer(); + + int RunPaxos(); + + int ReadyBench(); + + int Write(const std::string & sBenchValue); + + int Write(const int iGroupIdx, const std::string & sBenchValue); + +private: + int MakeLogStoragePath(std::string & sLogStoragePath); + +private: + phxpaxos::NodeInfo m_oMyNode; + phxpaxos::NodeInfoList m_vecNodeList; + + int m_iGroupCount; + std::vector m_vecSMList; + + phxpaxos::Node * m_poPaxosNode; +}; + +} + + diff --git a/src/benchmark/bench_sm.cpp b/src/benchmark/bench_sm.cpp new file mode 100644 index 000000000..732a88059 --- /dev/null +++ b/src/benchmark/bench_sm.cpp @@ -0,0 +1,47 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "bench_sm.h" + +using namespace phxpaxos; + +namespace bench +{ + +BenchSM :: BenchSM(const phxpaxos::nodeid_t llMyNodeID, const int iGroupIdx) + : m_llMyNodeID(llMyNodeID), m_iGroupIdx(iGroupIdx) +{ +} + +bool BenchSM :: Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, SMCtx * poSMCtx) +{ + //bench sm do nothing + return true; +} + +const int BenchSM :: GetGroupIdx() const +{ + return m_iGroupIdx; +} + +} + diff --git a/src/benchmark/bench_sm.h b/src/benchmark/bench_sm.h new file mode 100644 index 000000000..58d1022bf --- /dev/null +++ b/src/benchmark/bench_sm.h @@ -0,0 +1,70 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/sm.h" +#include "phxpaxos/options.h" +#include +#include + +namespace bench +{ + +class BenchSM : public phxpaxos::StateMachine +{ +public: + BenchSM(const phxpaxos::nodeid_t llMyNodeID, const int iGroupIdx); + + bool Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, phxpaxos::SMCtx * poSMCtx); + + const int SMID() const { return 1; } + + //no checkpoint + bool ExecuteForCheckpoint(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue) { return true; } + + const uint64_t GetCheckpointInstanceID(const int iGroupIdx) const { return phxpaxos::NoCheckpoint; } + + const int GetGroupIdx() const; + +public: + //no checkpoint + int GetCheckpointState(const int iGroupIdx, std::string & sDirPath, + std::vector & vecFileList) { return 0; } + + //no checkpoint + int LoadCheckpointState(const int iGroupIdx, const std::string & sCheckpointTmpFileDirPath, + const std::vector & vecFileList, const uint64_t llCheckpointInstanceID) { return 0; } + + //no checkpoint + int LockCheckpointState() { return 0; } + + //no checkpoint + void UnLockCheckpointState() { } + +private: + phxpaxos::nodeid_t m_llMyNodeID; + int m_iGroupIdx; +}; + +} diff --git a/src/benchmark/fsync_bench.cpp b/src/benchmark/fsync_bench.cpp new file mode 100644 index 000000000..fc7a1b3e1 --- /dev/null +++ b/src/benchmark/fsync_bench.cpp @@ -0,0 +1,126 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +void RandValue(const int iSize, string & sValue) +{ + sValue = ""; + int iRealSize = rand() % iSize + iSize / 2; + + for (int i = 0; i < iRealSize; i++) + { + sValue += (rand() % 26 + 'a'); + } +} + +const uint64_t GetTimestampMS() +{ + uint64_t llNow; + struct timeval tv; + + gettimeofday(&tv, NULL); + + llNow = tv.tv_sec; + llNow *= 1000; + llNow += tv.tv_usec / 1000; + + return llNow; +} + +void benchfsync(const std::string & sFilePath) +{ + string sValue; + RandValue(100, sValue); + + int fd = open(sFilePath.c_str(), O_CREAT | O_RDWR | O_APPEND, S_IWRITE | S_IREAD); + if (fd == -1) + { + printf("open file fail %s\n", sFilePath.c_str()); + return; + } + + uint64_t llBeginTimeMs = GetTimestampMS(); + + const int iWriteCount = 100; + for (int i = 0; i < iWriteCount; i++) + { + int len = write(fd, sValue.data(), sValue.size()); + if (len != sValue.size()) + { + printf("write fail, writelen %d\n", len); + close(fd); + return; + } + fsync(fd); + } + + uint64_t llEndTimeMs = GetTimestampMS(); + int iRunTimeMs = llEndTimeMs - llBeginTimeMs; + int qps = (uint64_t)iWriteCount * 1000 / iRunTimeMs; + + printf("qps %d\n", qps); + close(fd); +} + +int main(int argc, char ** argv) +{ + vector filelist; + for (int i = 2; i < 30; i++) + { + if (argc >= i) + { + filelist.push_back(argv[u - 1]); + } + else + { + break; + } + } + + for (size_t i = 0; i < filelist.size(); i++) + { + if (fork() == 0) + { + benchfsync(filelist[i]); + exit(0); + } + } + + return 0; +} diff --git a/src/checkpoint/Makefile.define b/src/checkpoint/Makefile.define new file mode 100644 index 000000000..908295555 --- /dev/null +++ b/src/checkpoint/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libcheckpoint.a + +CHECKPOINT_OBJ=cp_mgr.o replayer.o cleaner.o + +CHECKPOINT_LIB=checkpoint src/comm:comm src/logstorage:logstorage src/sm-base:smbase include:include src/utils:utils src/config:config + +CHECKPOINT_SYS_LIB= + +CHECKPOINT_INCS=$(SRC_BASE_PATH)/src/checkpoint + +CHECKPOINT_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/checkpoint/cleaner.cpp b/src/checkpoint/cleaner.cpp new file mode 100644 index 000000000..c7535b842 --- /dev/null +++ b/src/checkpoint/cleaner.cpp @@ -0,0 +1,203 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "cleaner.h" +#include "phxpaxos/storage.h" +#include "comm_include.h" +#include "config_include.h" +#include "cp_mgr.h" +#include "sm_base.h" + +namespace phxpaxos +{ + +Cleaner :: Cleaner( + Config * poConfig, + SMFac * poSMFac, + LogStorage * poLogStorage, + CheckpointMgr * poCheckpointMgr) + : m_poConfig(poConfig), + m_poSMFac(poSMFac), + m_poLogStorage(poLogStorage), + m_poCheckpointMgr(poCheckpointMgr), + m_llLastSave(0), + m_bCanrun(false), + m_bIsPaused(true), + m_bIsEnd(false), + m_bIsStart(false), + m_llHoldCount(CAN_DELETE_DELTA) +{ +} + +Cleaner :: ~Cleaner() +{ +} + +void Cleaner :: Stop() +{ + m_bIsEnd = true; + if (m_bIsStart) + { + join(); + } +} + +void Cleaner :: Pause() +{ + m_bCanrun = false; +} + +void Cleaner :: Continue() +{ + m_bIsPaused = false; + m_bCanrun = true; +} + +const bool Cleaner :: IsPaused() const +{ + return m_bIsPaused; +} + +void Cleaner :: run() +{ + m_bIsStart = true; + Continue(); + + uint64_t llInstanceID = m_poCheckpointMgr->GetMinChosenInstanceID(); + + while (true) + { + if (m_bIsEnd) + { + PLGHead("Checkpoint.Cleaner [END]"); + return; + } + + if (!m_bCanrun) + { + PLGImp("Pausing, sleep"); + m_bIsPaused = true; + Time::MsSleep(1000); + continue; + } + + bool bDeleteRet = DeleteOne(llInstanceID); + if (bDeleteRet) + { + PLGImp("delete one done, instanceid %lu", llInstanceID); + llInstanceID++; + } + else + { + PLGImp("no need to delete, max deleted instanceid %lu checkpoint instanceid %lu now instanceid %lu", + llInstanceID, m_poSMFac->GetCheckpointInstanceID(m_poConfig->GetMyGroupIdx()), + m_poCheckpointMgr->GetMaxChosenInstanceID()); + + Time::MsSleep(1000); + } + } +} + +int Cleaner :: FixMinChosenInstanceID(const uint64_t llOldMinChosenInstanceID) +{ + uint64_t llCPInstanceID = m_poSMFac->GetCheckpointInstanceID(m_poConfig->GetMyGroupIdx()) + 1; + uint64_t llFixMinChosenInstanceID = llOldMinChosenInstanceID; + int ret = 0; + + for (uint64_t llInstanceID = llOldMinChosenInstanceID; llInstanceID < llOldMinChosenInstanceID + DELETE_SAVE_INTERVAL; + llInstanceID++) + { + if (llInstanceID >= llCPInstanceID) + { + break; + } + + std::string sValue; + ret = m_poLogStorage->Get(m_poConfig->GetMyGroupIdx(), llInstanceID, sValue); + if (ret != 0 && ret != 1) + { + return -1; + } + else if (ret == 1) + { + llFixMinChosenInstanceID = llInstanceID + 1; + } + else + { + break; + } + } + + if (llFixMinChosenInstanceID > llOldMinChosenInstanceID) + { + ret = m_poCheckpointMgr->SetMinChosenInstanceID(llFixMinChosenInstanceID); + if (ret != 0) + { + return ret; + } + } + + PLGImp("ok, old minchosen %lu fix minchosen %lu", llOldMinChosenInstanceID, llFixMinChosenInstanceID); + + return 0; +} + +bool Cleaner :: DeleteOne(const uint64_t llInstanceID) +{ + uint64_t llCPInstanceID = m_poSMFac->GetCheckpointInstanceID(m_poConfig->GetMyGroupIdx()) + 1; + if (llInstanceID + m_llHoldCount >= llCPInstanceID) + { + return false; + } + + WriteOptions oWriteOptions; + oWriteOptions.bSync = false; + + int ret = m_poLogStorage->Del(oWriteOptions, m_poConfig->GetMyGroupIdx(), llInstanceID); + if (ret != 0) + { + return false; + } + + m_poCheckpointMgr->SetMinChosenInstanceIDCache(llInstanceID); + + if (llInstanceID >= m_llLastSave + DELETE_SAVE_INTERVAL) + { + int ret = m_poCheckpointMgr->SetMinChosenInstanceID(llInstanceID + 1); + if (ret != 0) + { + PLGErr("SetMinChosenInstanceID fail, now delete instanceid %lu", llInstanceID); + return false; + } + + m_llLastSave = llInstanceID; + } + + return true; +} + +void Cleaner :: SetHoldPaxosLogCount(const uint64_t llHoldCount) +{ + m_llHoldCount = llHoldCount; +} + +} + diff --git a/src/checkpoint/cleaner.h b/src/checkpoint/cleaner.h new file mode 100644 index 000000000..11ad00d35 --- /dev/null +++ b/src/checkpoint/cleaner.h @@ -0,0 +1,84 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include "utils_include.h" + +namespace phxpaxos +{ + +#define CAN_DELETE_DELTA 10000000 +#define DELETE_SAVE_INTERVAL 100 + +class Config; +class SMFac; +class LogStorage; +class CheckpointMgr; + +class Cleaner : public Thread +{ +public: + Cleaner( + Config * poConfig, + SMFac * poSMFac, + LogStorage * poLogStorage, + CheckpointMgr * poCheckpointMgr); + + ~Cleaner(); + + void Stop(); + + void run(); + + void Pause(); + + void Continue(); + + const bool IsPaused() const; + +public: + void SetHoldPaxosLogCount(const uint64_t llHoldCount); + + int FixMinChosenInstanceID(const uint64_t llOldMinChosenInstanceID); + +private: + bool DeleteOne(const uint64_t llInstanceID); + +private: + Config * m_poConfig; + SMFac * m_poSMFac; + LogStorage * m_poLogStorage; + CheckpointMgr * m_poCheckpointMgr; + + uint64_t m_llLastSave; + + bool m_bCanrun; + bool m_bIsPaused; + + bool m_bIsEnd; + bool m_bIsStart; + + uint64_t m_llHoldCount; +}; + +} diff --git a/src/checkpoint/cp_mgr.cpp b/src/checkpoint/cp_mgr.cpp new file mode 100644 index 000000000..403da5cb8 --- /dev/null +++ b/src/checkpoint/cp_mgr.cpp @@ -0,0 +1,184 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "cp_mgr.h" +#include "comm_include.h" +#include "sm_base.h" +#include "phxpaxos/storage.h" +#include "config_include.h" + +namespace phxpaxos +{ + +CheckpointMgr :: CheckpointMgr( + Config * poConfig, + SMFac * poSMFac, + LogStorage * poLogStorage, + const bool bUseCheckpointReplayer) + : m_poConfig(poConfig), + m_poLogStorage(poLogStorage), + m_poSMFac(poSMFac), + m_oReplayer(poConfig, poSMFac, poLogStorage, this), + m_oCleaner(poConfig, poSMFac, poLogStorage, this), + m_llMinChosenInstanceID(0), + m_bInAskforCheckpointMode(false), + m_bUseCheckpointReplayer(bUseCheckpointReplayer) +{ + m_llLastAskforCheckpointTime = 0; +} + +CheckpointMgr :: ~CheckpointMgr() +{ +} + +int CheckpointMgr :: Init() +{ + int ret = m_poLogStorage->GetMinChosenInstanceID(m_poConfig->GetMyGroupIdx(), m_llMinChosenInstanceID); + if (ret != 0) + { + return ret; + } + + ret = m_oCleaner.FixMinChosenInstanceID(m_llMinChosenInstanceID); + if (ret != 0) + { + return ret; + } + + return 0; +} + +void CheckpointMgr :: Start() +{ + if (m_bUseCheckpointReplayer) + { + m_oReplayer.start(); + } + m_oCleaner.start(); +} + +void CheckpointMgr :: Stop() +{ + if (m_bUseCheckpointReplayer) + { + m_oReplayer.Stop(); + } + m_oCleaner.Stop(); +} + +Replayer * CheckpointMgr :: GetReplayer() +{ + return &m_oReplayer; +} + +Cleaner * CheckpointMgr :: GetCleaner() +{ + return &m_oCleaner; +} + +int CheckpointMgr :: PrepareForAskforCheckpoint(const nodeid_t iSendNodeID) +{ + if (m_setNeedAsk.find(iSendNodeID) == m_setNeedAsk.end()) + { + m_setNeedAsk.insert(iSendNodeID); + } + + if (m_llLastAskforCheckpointTime == 0) + { + m_llLastAskforCheckpointTime = Time::GetTimestampMS(); + } + + uint64_t llNowTime = Time::GetTimestampMS(); + if (llNowTime > m_llLastAskforCheckpointTime + 60000) + { + PLGImp("no majority reply, just ask for checkpoint"); + } + else + { + + if ((int)m_setNeedAsk.size() < m_poConfig->GetMajorityCount()) + { + PLGImp("Need more other tell us need to askforcheckpoint"); + return -2; + } + } + + m_llLastAskforCheckpointTime = 0; + m_bInAskforCheckpointMode = true; + + return 0; +} + +///////////////////////////////////////////////////// + +const bool CheckpointMgr :: InAskforcheckpointMode() const +{ + return m_bInAskforCheckpointMode; +} + +void CheckpointMgr :: ExitCheckpointMode() +{ + m_bInAskforCheckpointMode = false; +} + +const uint64_t CheckpointMgr :: GetCheckpointInstanceID() const +{ + return m_poSMFac->GetCheckpointInstanceID(m_poConfig->GetMyGroupIdx()); +} + +const uint64_t CheckpointMgr :: GetMinChosenInstanceID() const +{ + return m_llMinChosenInstanceID; +} + +int CheckpointMgr :: SetMinChosenInstanceID(const uint64_t llMinChosenInstanceID) +{ + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + + int ret = m_poLogStorage->SetMinChosenInstanceID(oWriteOptions, m_poConfig->GetMyGroupIdx(), llMinChosenInstanceID); + if (ret != 0) + { + return ret; + } + + m_llMinChosenInstanceID = llMinChosenInstanceID; + + return 0; +} + +void CheckpointMgr :: SetMinChosenInstanceIDCache(const uint64_t llMinChosenInstanceID) +{ + m_llMinChosenInstanceID = llMinChosenInstanceID; +} + +void CheckpointMgr :: SetMaxChosenInstanceID(const uint64_t llMaxChosenInstanceID) +{ + m_llMaxChosenInstanceID = llMaxChosenInstanceID; +} + +const uint64_t CheckpointMgr :: GetMaxChosenInstanceID() const +{ + return m_llMaxChosenInstanceID; +} + +} + diff --git a/src/checkpoint/cp_mgr.h b/src/checkpoint/cp_mgr.h new file mode 100644 index 000000000..f816ed10a --- /dev/null +++ b/src/checkpoint/cp_mgr.h @@ -0,0 +1,92 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "replayer.h" +#include "cleaner.h" +#include "phxpaxos/options.h" +#include + +namespace phxpaxos +{ + +class CheckpointMgr +{ +public: + CheckpointMgr( + Config * poConfig, + SMFac * poSMFac, + LogStorage * poLogStorage, + const bool bUseCheckpointReplayer); + + ~CheckpointMgr(); + + int Init(); + + void Start(); + + void Stop(); + + Replayer * GetReplayer(); + + Cleaner * GetCleaner(); + +public: + int PrepareForAskforCheckpoint(const nodeid_t iSendNodeID); + + const bool InAskforcheckpointMode() const; + + void ExitCheckpointMode(); + +public: + const uint64_t GetMinChosenInstanceID() const; + + int SetMinChosenInstanceID(const uint64_t llMinChosenInstanceID); + + void SetMinChosenInstanceIDCache(const uint64_t llMinChosenInstanceID); + + const uint64_t GetCheckpointInstanceID() const; + + const uint64_t GetMaxChosenInstanceID() const; + + void SetMaxChosenInstanceID(const uint64_t llMaxChosenInstanceID); + +private: + Config * m_poConfig; + LogStorage * m_poLogStorage; + SMFac * m_poSMFac; + + Replayer m_oReplayer; + Cleaner m_oCleaner; + + uint64_t m_llMinChosenInstanceID; + uint64_t m_llMaxChosenInstanceID; + +private: + bool m_bInAskforCheckpointMode; + std::set m_setNeedAsk; + uint64_t m_llLastAskforCheckpointTime; + + bool m_bUseCheckpointReplayer; +}; + +} diff --git a/src/checkpoint/replayer.cpp b/src/checkpoint/replayer.cpp new file mode 100644 index 000000000..316e7b156 --- /dev/null +++ b/src/checkpoint/replayer.cpp @@ -0,0 +1,136 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "replayer.h" +#include "phxpaxos/storage.h" +#include "sm_base.h" +#include "comm_include.h" +#include "config_include.h" +#include "cp_mgr.h" + +namespace phxpaxos +{ + +Replayer :: Replayer( + Config * poConfig, + SMFac * poSMFac, + LogStorage * poLogStorage, + CheckpointMgr * poCheckpointMgr) + : m_poConfig(poConfig), + m_poSMFac(poSMFac), + m_oPaxosLog(poLogStorage), + m_poCheckpointMgr(poCheckpointMgr), + m_bCanrun(false), + m_bIsPaused(true), + m_bIsEnd(false) +{ +} + +Replayer :: ~Replayer() +{ +} + +void Replayer :: Stop() +{ + m_bIsEnd = true; + join(); +} + +void Replayer :: Pause() +{ + m_bCanrun = false; +} + +void Replayer :: Continue() +{ + m_bIsPaused = false; + m_bCanrun = true; +} + +const bool Replayer:: IsPaused() const +{ + return m_bIsPaused; +} + +void Replayer :: run() +{ + PLGHead("Checkpoint.Replayer [START]"); + uint64_t llInstanceID = m_poSMFac->GetCheckpointInstanceID(m_poConfig->GetMyGroupIdx()) + 1; + + while (true) + { + if (m_bIsEnd) + { + PLGHead("Checkpoint.Replayer [END]"); + return; + } + + if (!m_bCanrun) + { + //PLGImp("Pausing, sleep"); + m_bIsPaused = true; + Time::MsSleep(1000); + continue; + } + + if (llInstanceID >= m_poCheckpointMgr->GetMaxChosenInstanceID()) + { + //PLGImp("now maxchosen instanceid %lu small than excute instanceid %lu, wait", + //m_poCheckpointMgr->GetMaxChosenInstanceID(), llInstanceID); + Time::MsSleep(1000); + continue; + } + + bool bPlayRet = PlayOne(llInstanceID); + if (bPlayRet) + { + PLGImp("Play one done, instanceid %lu", llInstanceID); + llInstanceID++; + } + else + { + PLGErr("Play one fail, instanceid %lu", llInstanceID); + Time::MsSleep(500); + } + } +} + +bool Replayer :: PlayOne(const uint64_t llInstanceID) +{ + AcceptorStateData oState; + int ret = m_oPaxosLog.ReadState(m_poConfig->GetMyGroupIdx(), llInstanceID, oState); + if (ret != 0) + { + return false; + } + + bool bExecuteRet = m_poSMFac->ExecuteForCheckpoint( + m_poConfig->GetMyGroupIdx(), llInstanceID, oState.acceptedvalue()); + if (!bExecuteRet) + { + PLGErr("Checkpoint sm excute fail, instanceid %lu", llInstanceID); + } + + return bExecuteRet; +} + +} + diff --git a/src/checkpoint/replayer.h b/src/checkpoint/replayer.h new file mode 100644 index 000000000..233aa27db --- /dev/null +++ b/src/checkpoint/replayer.h @@ -0,0 +1,70 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "utils_include.h" +#include "paxos_log.h" + +namespace phxpaxos +{ + +class Config; +class SMFac; +class LogStorage; +class CheckpointMgr; + +class Replayer : public Thread +{ +public: + Replayer( + Config * poConfig, + SMFac * poSMFac, + LogStorage * poLogStorage, + CheckpointMgr * poCheckpointMgr); + + ~Replayer(); + + void Stop(); + + void run(); + + void Pause(); + + void Continue(); + + const bool IsPaused() const; + +private: + bool PlayOne(const uint64_t llInstanceID); + +private: + Config * m_poConfig; + SMFac * m_poSMFac; + PaxosLog m_oPaxosLog; + CheckpointMgr * m_poCheckpointMgr; + + bool m_bCanrun; + bool m_bIsPaused; + bool m_bIsEnd; +}; + +} diff --git a/src/comm/Makefile.define b/src/comm/Makefile.define new file mode 100644 index 000000000..dae462ee5 --- /dev/null +++ b/src/comm/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libcomm.a + +COMM_OBJ=paxos_msg.pb.o breakpoint.o options.o inside_options.o logger.o + +COMM_LIB=comm include:include src/utils:utils + +COMM_SYS_LIB=$(PROTOBUF_LIB_PATH)/libprotobuf.a + +COMM_INCS=$(SRC_BASE_PATH)/src/comm $(PROTOBUF_INCLUDE_PATH) + +COMM_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/comm/breakpoint.cpp b/src/comm/breakpoint.cpp new file mode 100644 index 000000000..03747db8c --- /dev/null +++ b/src/comm/breakpoint.cpp @@ -0,0 +1,100 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "phxpaxos/breakpoint.h" + +namespace phxpaxos +{ + +Breakpoint * Breakpoint :: m_poBreakpoint = nullptr; + +Breakpoint :: Breakpoint() +{ +} + +void Breakpoint :: SetInstance(Breakpoint * poBreakpoint) +{ + m_poBreakpoint = poBreakpoint; +} + +Breakpoint * Breakpoint :: Instance() +{ + if (m_poBreakpoint != nullptr) + { + return m_poBreakpoint; + } + + static Breakpoint oBreakpoint; + return &oBreakpoint; +} + +ProposerBP * Breakpoint :: GetProposerBP() +{ + return &m_oProposerBP; +} + +AcceptorBP * Breakpoint :: GetAcceptorBP() +{ + return &m_oAcceptorBP; +} + +LearnerBP * Breakpoint :: GetLearnerBP() +{ + return &m_oLearnerBP; +} + +InstanceBP * Breakpoint :: GetInstanceBP() +{ + return &m_oInstanceBP; +} + +CommiterBP * Breakpoint :: GetCommiterBP() +{ + return &m_oCommiterBP; +} + +IOLoopBP * Breakpoint :: GetIOLoopBP() +{ + return &m_oIOLoopBP; +} + +NetworkBP * Breakpoint :: GetNetworkBP() +{ + return &m_oNetworkBP; +} + +LogStorageBP * Breakpoint :: GetLogStorageBP() +{ + return &m_oLogStorageBP; +} + +AlgorithmBaseBP * Breakpoint :: GetAlgorithmBaseBP() +{ + return &m_oAlgorithmBaseBP; +} + +CheckpointBP * Breakpoint :: GetCheckpointBP() +{ + return &m_oCheckpointBP; +} + +} + diff --git a/src/comm/comm_include.h b/src/comm/comm_include.h new file mode 100644 index 000000000..19daa7670 --- /dev/null +++ b/src/comm/comm_include.h @@ -0,0 +1,26 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "./paxos_msg.pb.h" +#include "phxpaxos/breakpoint.h" +#include "utils_include.h" diff --git a/src/comm/commdef.h b/src/comm/commdef.h new file mode 100644 index 000000000..9b355b681 --- /dev/null +++ b/src/comm/commdef.h @@ -0,0 +1,125 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include "phxpaxos/options.h" +#include "inside_options.h" +#include "phxpaxos/def.h" +#include +#include "logger.h" + +using std::string; + +namespace phxpaxos +{ + +#define NLDebug(format, args...) LOG_VERBOSE("DEBUG: %s " format, __func__, ## args); +#define NLErr(format, args...) LOG_ERROR("ERR: %s " format, __func__, ## args); + +#define PLErr(format, args...) LOG_ERROR("ERR: %s::%s " format, typeid(this).name(), __func__, ## args); +#define PLImp(format, args...) LOG_INFO("Showy: %s::%s " format, typeid(this).name(), __func__, ## args); +#define PLHead(format, args...) LOG_WARNING("Imp: %s::%s " format, typeid(this).name(), __func__, ## args); +#define PLDebug(format, args...) LOG_VERBOSE("DEBUG: %s::%s " format, typeid(this).name(), __func__, ## args); + +#define PLGErr(format, args...) LOG_ERROR("ERR(%d): %s::%s " format, m_poConfig->GetMyGroupIdx(), typeid(this).name(), __func__, ## args); +#define PLGImp(format, args...) LOG_INFO("Showy(%d): %s::%s " format, m_poConfig->GetMyGroupIdx(), typeid(this).name(), __func__, ## args); +#define PLGHead(format, args...) LOG_WARNING("Imp(%d): %s::%s " format, m_poConfig->GetMyGroupIdx(), typeid(this).name(), __func__, ## args); +#define PLGDebug(format, args...) LOG_VERBOSE("DEBUG(%d): %s::%s " format, m_poConfig->GetMyGroupIdx(), typeid(this).name(), __func__, ## args); + +#define PLG1Err(format, args...) LOG_ERROR("ERR(%d): %s::%s " format, m_iMyGroupIdx, typeid(this).name(), __func__, ## args); +#define PLG1Imp(format, args...) LOG_INFO("Showy(%d): %s::%s " format, m_iMyGroupIdx, typeid(this).name(), __func__, ## args); +#define PLG1Head(format, args...) LOG_WARNING("Imp(%d): %s::%s " format, m_iMyGroupIdx, typeid(this).name(), __func__, ## args); +#define PLG1Debug(format, args...) LOG_VERBOSE("DEBUG(%d): %s::%s " format, m_iMyGroupIdx, typeid(this).name(), __func__, ## args); + + +#define nullvalue "nullvalue" + +#define CRC32SKIP 8 +#define NET_CRC32SKIP 7 + +//network protocal +#define GROUPIDXLEN (sizeof(int)) +#define HEADLEN_LEN (sizeof(uint16_t)) +#define CHECKSUM_LEN (sizeof(uint32_t)) + +//max queue memsize +#define MAX_QUEUE_MEM_SIZE 209715200 + +enum MsgCmd +{ + MsgCmd_PaxosMsg = 1, + MsgCmd_CheckpointMsg = 2, +}; + +enum PaxosMsgType +{ + MsgType_PaxosPrepare = 1, + MsgType_PaxosPrepareReply = 2, + MsgType_PaxosAccept = 3, + MsgType_PaxosAcceptReply = 4, + MsgType_PaxosLearner_AskforLearn = 5, + MsgType_PaxosLearner_SendLearnValue = 6, + MsgType_PaxosLearner_ProposerSendSuccess = 7, + MsgType_PaxosProposal_SendNewValue = 8, + MsgType_PaxosLearner_SendNowInstanceID = 9, + MsgType_PaxosLearner_ComfirmAskforLearn = 10, + MsgType_PaxosLearner_SendLearnValue_Ack = 11, + MsgType_PaxosLearner_AskforCheckpoint = 12, + MsgType_PaxosLearner_OnAskforCheckpoint = 13, +}; + +enum PaxosMsgFlagType +{ + PaxosMsgFlagType_SendLearnValue_NeedAck = 1, +}; + +enum CheckpointMsgType +{ + CheckpointMsgType_SendFile = 1, + CheckpointMsgType_SendFile_Ack = 2, +}; + +enum CheckpointSendFileFlag +{ + CheckpointSendFileFlag_BEGIN = 1, + CheckpointSendFileFlag_ING = 2, + CheckpointSendFileFlag_END = 3, +}; + +enum CheckpointSendFileAckFlag +{ + CheckpointSendFileAckFlag_OK = 1, + CheckpointSendFileAckFlag_Fail = 2, +}; + +enum TimerType +{ + Timer_Proposer_Prepare_Timeout = 1, + Timer_Proposer_Accept_Timeout = 2, + Timer_Learner_Askforlearn_noop = 3, + Timer_Instance_Commit_Timeout = 4, +}; + + +} diff --git a/src/comm/inside_options.cpp b/src/comm/inside_options.cpp new file mode 100644 index 000000000..fb5529198 --- /dev/null +++ b/src/comm/inside_options.cpp @@ -0,0 +1,238 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "inside_options.h" +#include "commdef.h" +#include "utils_include.h" + +namespace phxpaxos +{ + +InsideOptions :: InsideOptions() +{ + m_bIsLargeBufferMode = false; + m_bIsIMFollower = false; +} + +InsideOptions :: ~InsideOptions() +{ +} + +InsideOptions * InsideOptions :: Instance() +{ + static InsideOptions oInsideOptions; + return &oInsideOptions; +} + +void InsideOptions :: SetAsLargeBufferMode() +{ + m_bIsLargeBufferMode = true; +} + +void InsideOptions :: SetAsFollower() +{ + m_bIsIMFollower = true; +} + +const int InsideOptions :: GetMaxBufferSize() +{ + if (m_bIsLargeBufferMode) + { + return 52428800; + } + else + { + return 10485760; + } +} + +const int InsideOptions :: GetStartPrepareTimeoutMs() +{ + if (m_bIsLargeBufferMode) + { + return 15000; + } + else + { + return 2000; + } +} + +const int InsideOptions :: GetStartAcceptTimeoutMs() +{ + if (m_bIsLargeBufferMode) + { + return 15000; + } + else + { + return 2000; + } +} + +const int InsideOptions :: GetMaxPrepareTimeoutMs() +{ + if (m_bIsLargeBufferMode) + { + return 90000; + } + else + { + return 8000; + } +} + +const int InsideOptions :: GetMaxAcceptTimeoutMs() +{ + if (m_bIsLargeBufferMode) + { + return 90000; + } + else + { + return 8000; + } +} + +const int InsideOptions :: GetMaxQueueLen() +{ + if (m_bIsLargeBufferMode) + { + return 1024; + } + else + { + return 10240; + } +} + +const int InsideOptions :: GetAskforLearnInterval() +{ + if (!m_bIsIMFollower) + { + if (m_bIsLargeBufferMode) + { + return 50000 + (OtherUtils::FastRand() % 10000); + } + else + { + return 2500 + (OtherUtils::FastRand() % 500); + } + } + else + { + if (m_bIsLargeBufferMode) + { + return 30000 + (OtherUtils::FastRand() % 15000); + } + else + { + return 2000 + (OtherUtils::FastRand() % 1000); + } + } +} + +const int InsideOptions :: GetLeanerReceiver_Ack_Lead() +{ + if (m_bIsLargeBufferMode) + { + return 5; + } + else + { + return 25; + } +} + +const int InsideOptions :: GetLeanerSenderPrepareTimeoutMs() +{ + if (m_bIsLargeBufferMode) + { + return 5000; + } + else + { + return 5000; + } +} + +const int InsideOptions :: GetLeanerSender_Ack_TimeoutMs() +{ + if (m_bIsLargeBufferMode) + { + return 60000; + } + else + { + return 5000; + } +} + +const int InsideOptions :: GetLeanerSender_Ack_Lead() +{ + if (m_bIsLargeBufferMode) + { + return 11; + } + else + { + return 51; + } +} + +const int InsideOptions :: GetTcpOutQueueDropTimeMs() +{ + if (m_bIsLargeBufferMode) + { + return 20000; + } + else + { + return 5000; + } +} + +const int InsideOptions :: GetLogFileMaxSize() +{ + if (m_bIsLargeBufferMode) + { + return 524288000; + } + else + { + return 104857600; + } +} + +const int InsideOptions :: GetTcpConnectionNonActiveTimeout() +{ + if (m_bIsLargeBufferMode) + { + return 600000; + } + else + { + return 60000; + } +} + +} + diff --git a/src/comm/inside_options.h b/src/comm/inside_options.h new file mode 100644 index 000000000..e0a93ffbc --- /dev/null +++ b/src/comm/inside_options.h @@ -0,0 +1,93 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include + +namespace phxpaxos +{ + +#define MAX_VALUE_SIZE (InsideOptions::Instance()->GetMaxBufferSize()) +#define START_PREPARE_TIMEOUTMS (InsideOptions::Instance()->GetStartPrepareTimeoutMs()) +#define START_ACCEPT_TIMEOUTMS (InsideOptions::Instance()->GetStartAcceptTimeoutMs()) +#define MAX_PREPARE_TIMEOUTMS (InsideOptions::Instance()->GetMaxPrepareTimeoutMs()) +#define MAX_ACCEPT_TIMEOUTMS (InsideOptions::Instance()->GetMaxAcceptTimeoutMs()) +#define QUEUE_MAXLENGTH (InsideOptions::Instance()->GetMaxQueueLen()) +#define ASKFORLEARN_NOOP_INTERVAL (InsideOptions::Instance()->GetAskforLearnInterval()) +#define SENDLEARNVALUE_ACK_LEAD (InsideOptions::Instance()->GetLeanerReceiver_Ack_Lead()) +#define LearnerSender_PREPARE_TIMEOUT (InsideOptions::Instance()->GetLeanerSenderPrepareTimeoutMs()) +#define LearnerSender_ACK_TIMEOUT (InsideOptions::Instance()->GetLeanerSender_Ack_TimeoutMs()) +#define LearnerSender_ACK_LEAD (InsideOptions::Instance()->GetLeanerSender_Ack_Lead()) +#define TCP_QUEUE_MAXLEN (InsideOptions::Instance()->GetMaxQueueLen()) +#define UDP_QUEUE_MAXLEN (InsideOptions::Instance()->GetMaxQueueLen()) +#define TCP_OUTQUEUE_DROP_TIMEMS (InsideOptions::Instance()->GetTcpOutQueueDropTimeMs()) +#define LOG_FILE_MAX_SIZE (InsideOptions::Instance()->GetLogFileMaxSize()) +#define CONNECTTION_NONACTIVE_TIMEOUT (InsideOptions::Instance()->GetTcpConnectionNonActiveTimeout()) + +class InsideOptions +{ +public: + InsideOptions(); + ~InsideOptions(); + + static InsideOptions * Instance(); + + void SetAsLargeBufferMode(); + + void SetAsFollower(); + +public: + const int GetMaxBufferSize(); + + const int GetStartPrepareTimeoutMs(); + + const int GetStartAcceptTimeoutMs(); + + const int GetMaxPrepareTimeoutMs(); + + const int GetMaxAcceptTimeoutMs(); + + const int GetMaxQueueLen(); + + const int GetAskforLearnInterval(); + + const int GetLeanerReceiver_Ack_Lead(); + + const int GetLeanerSenderPrepareTimeoutMs(); + + const int GetLeanerSender_Ack_TimeoutMs(); + + const int GetLeanerSender_Ack_Lead(); + + const int GetTcpOutQueueDropTimeMs(); + + const int GetLogFileMaxSize(); + + const int GetTcpConnectionNonActiveTimeout(); + +private: + bool m_bIsLargeBufferMode; + bool m_bIsIMFollower; +}; + +} diff --git a/src/comm/logger.cpp b/src/comm/logger.cpp new file mode 100644 index 000000000..fa4938c33 --- /dev/null +++ b/src/comm/logger.cpp @@ -0,0 +1,174 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "logger.h" +#include +#include +using namespace std; + +namespace phxpaxos +{ + +Logger :: Logger() + : m_pLogFunc(nullptr) +{ +} + +Logger :: ~Logger() +{ +} + +Logger * Logger :: Instance() +{ + static Logger oLogger; + return &oLogger; +} + +void Logger :: InitLogger(const LogLevel eLogLevel) +{ + m_eLogLevel = eLogLevel; +} + +void Logger :: SetLogFunc(LogFunc pLogFunc) +{ + m_pLogFunc = pLogFunc; +} + + +void Logger :: LogError(const char * pcFormat, ...) +{ + string newFormat = "\033[41;37m " + string(pcFormat) + " \033[0m"; + + if (m_pLogFunc != nullptr) + { + va_list args; + va_start(args, pcFormat); + m_pLogFunc(static_cast(LogLevel::LogLevel_Error), newFormat.c_str(), args); + va_end(args); + return; + } + + if (m_eLogLevel < LogLevel::LogLevel_Error) + { + return; + } + + char sBuf[1024] = {0}; + va_list args; + va_start(args, pcFormat); + vsnprintf(sBuf, sizeof(sBuf), newFormat.c_str(), args); + va_end(args); + + m_oMutex.lock(); + printf("%s\n", sBuf); + m_oMutex.unlock(); +} + +void Logger :: LogWarning(const char * pcFormat, ...) +{ + string newFormat = "\033[44;37m " + string(pcFormat) + " \033[0m"; + + if (m_pLogFunc != nullptr) + { + va_list args; + va_start(args, pcFormat); + m_pLogFunc(static_cast(LogLevel::LogLevel_Warning), newFormat.c_str(), args); + va_end(args); + return; + } + + if (m_eLogLevel < LogLevel::LogLevel_Warning) + { + return; + } + + char sBuf[1024] = {0}; + va_list args; + va_start(args, pcFormat); + vsnprintf(sBuf, sizeof(sBuf), newFormat.c_str(), args); + va_end(args); + + m_oMutex.lock(); + printf("%s\n", sBuf); + m_oMutex.unlock(); +} + + +void Logger :: LogInfo(const char * pcFormat, ...) +{ + string newFormat = "\033[45;37m " + string(pcFormat) + " \033[0m"; + + if (m_pLogFunc != nullptr) + { + va_list args; + va_start(args, pcFormat); + m_pLogFunc(static_cast(LogLevel::LogLevel_Info), newFormat.c_str(), args); + va_end(args); + return; + } + + if (m_eLogLevel < LogLevel::LogLevel_Info) + { + return; + } + + char sBuf[1024] = {0}; + va_list args; + va_start(args, pcFormat); + vsnprintf(sBuf, sizeof(sBuf), newFormat.c_str(), args); + va_end(args); + + m_oMutex.lock(); + printf("%s\n", sBuf); + m_oMutex.unlock(); +} + +void Logger :: LogVerbose(const char * pcFormat, ...) +{ + string newFormat = "\033[45;37m " + string(pcFormat) + " \033[0m"; + + if (m_pLogFunc != nullptr) + { + va_list args; + va_start(args, pcFormat); + m_pLogFunc(static_cast(LogLevel::LogLevel_Verbose), newFormat.c_str(), args); + va_end(args); + return; + } + + if (m_eLogLevel < LogLevel::LogLevel_Verbose) + { + return; + } + + char sBuf[1024] = {0}; + va_list args; + va_start(args, pcFormat); + vsnprintf(sBuf, sizeof(sBuf), pcFormat, args); + va_end(args); + + m_oMutex.lock(); + printf("%s\n", sBuf); + m_oMutex.unlock(); +} + +} + diff --git a/src/comm/logger.h b/src/comm/logger.h new file mode 100644 index 000000000..bfdf584dd --- /dev/null +++ b/src/comm/logger.h @@ -0,0 +1,67 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/log.h" +#include "utils_include.h" +#include + +namespace phxpaxos +{ + +#define LOGGER (Logger::Instance()) +#define LOG_ERROR(format, args...)\ + LOGGER->LogError(format, ## args); +#define LOG_WARNING(format, args...)\ + LOGGER->LogWarning(format, ## args); +#define LOG_INFO(format, args...)\ + LOGGER->LogInfo(format, ## args); +#define LOG_VERBOSE(format, args...)\ + LOGGER->LogVerbose(format, ## args); + +class Logger +{ +public: + Logger(); + ~Logger(); + + static Logger * Instance(); + + void InitLogger(const LogLevel eLogLevel); + + void SetLogFunc(LogFunc pLogFunc); + + void LogError(const char * pcFormat, ...); + + void LogWarning(const char * pcFormat, ...); + + void LogInfo(const char * pcFormat, ...); + + void LogVerbose(const char * pcFormat, ...); + +private: + LogLevel m_eLogLevel; + LogFunc m_pLogFunc; + Mutex m_oMutex; +}; + +} diff --git a/src/comm/msg_transport.h b/src/comm/msg_transport.h new file mode 100644 index 000000000..8e617e2df --- /dev/null +++ b/src/comm/msg_transport.h @@ -0,0 +1,53 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/options.h" + +namespace phxpaxos +{ + +enum Message_SendType +{ + Message_SendType_UDP = 0, + Message_SendType_TCP = 1, +}; + +class MsgTransport +{ +public: + virtual ~MsgTransport() {} + + virtual int SendMessage(const nodeid_t iSendtoNodeID, const std::string & sBuffer, + const int iSendType = Message_SendType_UDP) = 0; + + virtual int BroadcastMessage(const std::string & sBuffer, + const int iSendType = Message_SendType_UDP) = 0; + + virtual int BroadcastMessageFollower(const std::string & sBuffer, + const int iSendType = Message_SendType_UDP) = 0; + + virtual int BroadcastMessageTempNode(const std::string & sBuffer, + const int iSendType = Message_SendType_UDP) = 0; +}; + +} diff --git a/src/comm/options.cpp b/src/comm/options.cpp new file mode 100644 index 000000000..ee73c92de --- /dev/null +++ b/src/comm/options.cpp @@ -0,0 +1,132 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "phxpaxos/options.h" +#include "commdef.h" +#include +#include +#include +#include +#include + +namespace phxpaxos +{ + +NodeInfo :: NodeInfo() + : m_iNodeID(nullnode), m_sIP(""), m_iPort(-1) +{ +} + +NodeInfo :: NodeInfo(const nodeid_t iNodeID) + : m_iNodeID(iNodeID), m_sIP(""), m_iPort(-1) +{ + ParseNodeID(); +} + +NodeInfo :: NodeInfo(const std::string & sIP, const int iPort) + : m_iNodeID(nullnode), m_sIP(sIP), m_iPort(iPort) +{ + MakeNodeID(); +} + +const nodeid_t NodeInfo :: GetNodeID() const +{ + return m_iNodeID; +} + +const std::string & NodeInfo :: GetIP() const +{ + return m_sIP; +} + +const int NodeInfo :: GetPort() const +{ + return m_iPort; +} + +void NodeInfo :: SetIPPort(const std::string & sIP, const int iPort) +{ + m_sIP = sIP; + m_iPort = iPort; + MakeNodeID(); +} + +void NodeInfo :: SetNodeID(const nodeid_t iNodeID) +{ + m_iNodeID = iNodeID; + ParseNodeID(); +} + +void NodeInfo :: MakeNodeID() +{ + uint32_t iIP = (uint32_t)inet_addr(m_sIP.c_str()); + assert(iIP != (uint32_t)-1); + + m_iNodeID = (((uint64_t)iIP) << 32) | m_iPort; + + //PLImp("ip %s ip %u port %d nodeid %lu", m_sIP.c_str(), iIP, m_iPort, m_iNodeID); +} + +void NodeInfo :: ParseNodeID() +{ + m_iPort = m_iNodeID & (0xffffffff); + + in_addr addr; + addr.s_addr = m_iNodeID >> 32; + + m_sIP = std::string(inet_ntoa(addr)); + + //PLImp("nodeid %lu ip %s ip %u port %d", m_iNodeID, m_sIP.c_str(), addr.s_addr, m_iPort); +} + +///////////////////////////////////////////////////////////// + +GroupSMInfo :: GroupSMInfo() +{ + iGroupIdx = -1; + bIsUseMaster = false; +} + +///////////////////////////////////////////////////////////// + +Options :: Options() +{ + poLogStorage = nullptr; + + poNetWork = nullptr; + + iUDPMaxSize = 2048; + + iGroupCount = 1; + + poBreakpoint = nullptr; + + bIsLargeValueMode = false; + + pLogFunc = nullptr; + + eLogLevel = LogLevel::LogLevel_None; + + bUseCheckpointReplayer = false; +} + +} + diff --git a/src/comm/paxos_msg.pb.cc b/src/comm/paxos_msg.pb.cc new file mode 100644 index 000000000..749034aa1 --- /dev/null +++ b/src/comm/paxos_msg.pb.cc @@ -0,0 +1,4992 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: paxos_msg.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "paxos_msg.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace phxpaxos { + +namespace { + +const ::google::protobuf::Descriptor* Header_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Header_reflection_ = NULL; +const ::google::protobuf::Descriptor* PaxosMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + PaxosMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* CheckpointMsg_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + CheckpointMsg_reflection_ = NULL; +const ::google::protobuf::Descriptor* AcceptorStateData_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + AcceptorStateData_reflection_ = NULL; +const ::google::protobuf::Descriptor* PaxosNodeInfo_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + PaxosNodeInfo_reflection_ = NULL; +const ::google::protobuf::Descriptor* SystemVariables_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + SystemVariables_reflection_ = NULL; +const ::google::protobuf::Descriptor* MasterVariables_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + MasterVariables_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_paxos_5fmsg_2eproto() { + protobuf_AddDesc_paxos_5fmsg_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "paxos_msg.proto"); + GOOGLE_CHECK(file != NULL); + Header_descriptor_ = file->message_type(0); + static const int Header_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Header, gid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Header, rid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Header, cmdid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Header, version_), + }; + Header_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Header_descriptor_, + Header::default_instance_, + Header_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Header, _has_bits_[0]), + -1, + -1, + sizeof(Header), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Header, _internal_metadata_), + -1); + PaxosMsg_descriptor_ = file->message_type(1); + static const int PaxosMsg_offsets_[15] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, msgtype_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, instanceid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, nodeid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, proposalid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, proposalnodeid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, preacceptid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, preacceptnodeid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, rejectbypromiseid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, nowinstanceid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, minchoseninstanceid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, lastchecksum_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, flag_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, systemvariables_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, mastervariables_), + }; + PaxosMsg_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + PaxosMsg_descriptor_, + PaxosMsg::default_instance_, + PaxosMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, _has_bits_[0]), + -1, + -1, + sizeof(PaxosMsg), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosMsg, _internal_metadata_), + -1); + CheckpointMsg_descriptor_ = file->message_type(2); + static const int CheckpointMsg_offsets_[11] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, msgtype_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, nodeid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, flag_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, uuid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, sequence_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, checkpointinstanceid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, checksum_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, filepath_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, smid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, offset_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, buffer_), + }; + CheckpointMsg_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + CheckpointMsg_descriptor_, + CheckpointMsg::default_instance_, + CheckpointMsg_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, _has_bits_[0]), + -1, + -1, + sizeof(CheckpointMsg), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CheckpointMsg, _internal_metadata_), + -1); + AcceptorStateData_descriptor_ = file->message_type(3); + static const int AcceptorStateData_offsets_[7] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AcceptorStateData, instanceid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AcceptorStateData, promiseid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AcceptorStateData, promisenodeid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AcceptorStateData, acceptedid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AcceptorStateData, acceptednodeid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AcceptorStateData, acceptedvalue_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AcceptorStateData, checksum_), + }; + AcceptorStateData_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + AcceptorStateData_descriptor_, + AcceptorStateData::default_instance_, + AcceptorStateData_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AcceptorStateData, _has_bits_[0]), + -1, + -1, + sizeof(AcceptorStateData), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AcceptorStateData, _internal_metadata_), + -1); + PaxosNodeInfo_descriptor_ = file->message_type(4); + static const int PaxosNodeInfo_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosNodeInfo, rid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosNodeInfo, nodeid_), + }; + PaxosNodeInfo_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + PaxosNodeInfo_descriptor_, + PaxosNodeInfo::default_instance_, + PaxosNodeInfo_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosNodeInfo, _has_bits_[0]), + -1, + -1, + sizeof(PaxosNodeInfo), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(PaxosNodeInfo, _internal_metadata_), + -1); + SystemVariables_descriptor_ = file->message_type(5); + static const int SystemVariables_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemVariables, gid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemVariables, membership_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemVariables, version_), + }; + SystemVariables_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + SystemVariables_descriptor_, + SystemVariables::default_instance_, + SystemVariables_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemVariables, _has_bits_[0]), + -1, + -1, + sizeof(SystemVariables), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SystemVariables, _internal_metadata_), + -1); + MasterVariables_descriptor_ = file->message_type(6); + static const int MasterVariables_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterVariables, masternodeid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterVariables, version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterVariables, leasetime_), + }; + MasterVariables_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + MasterVariables_descriptor_, + MasterVariables::default_instance_, + MasterVariables_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterVariables, _has_bits_[0]), + -1, + -1, + sizeof(MasterVariables), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterVariables, _internal_metadata_), + -1); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_paxos_5fmsg_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Header_descriptor_, &Header::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + PaxosMsg_descriptor_, &PaxosMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + CheckpointMsg_descriptor_, &CheckpointMsg::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + AcceptorStateData_descriptor_, &AcceptorStateData::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + PaxosNodeInfo_descriptor_, &PaxosNodeInfo::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + SystemVariables_descriptor_, &SystemVariables::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + MasterVariables_descriptor_, &MasterVariables::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_paxos_5fmsg_2eproto() { + delete Header::default_instance_; + delete Header_reflection_; + delete PaxosMsg::default_instance_; + delete PaxosMsg_reflection_; + delete CheckpointMsg::default_instance_; + delete CheckpointMsg_reflection_; + delete AcceptorStateData::default_instance_; + delete AcceptorStateData_reflection_; + delete PaxosNodeInfo::default_instance_; + delete PaxosNodeInfo_reflection_; + delete SystemVariables::default_instance_; + delete SystemVariables_reflection_; + delete MasterVariables::default_instance_; + delete MasterVariables_reflection_; +} + +void protobuf_AddDesc_paxos_5fmsg_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\017paxos_msg.proto\022\010phxpaxos\"B\n\006Header\022\013\n" + "\003gid\030\001 \002(\004\022\013\n\003rid\030\002 \002(\004\022\r\n\005cmdid\030\003 \002(\005\022\017" + "\n\007version\030\004 \001(\005\"\315\002\n\010PaxosMsg\022\017\n\007MsgType\030" + "\001 \002(\005\022\022\n\nInstanceID\030\002 \001(\004\022\016\n\006NodeID\030\003 \001(" + "\004\022\022\n\nProposalID\030\004 \001(\004\022\026\n\016ProposalNodeID\030" + "\005 \001(\004\022\r\n\005Value\030\006 \001(\014\022\023\n\013PreAcceptID\030\007 \001(" + "\004\022\027\n\017PreAcceptNodeID\030\010 \001(\004\022\031\n\021RejectByPr" + "omiseID\030\t \001(\004\022\025\n\rNowInstanceID\030\n \001(\004\022\033\n\023" + "MinChosenInstanceID\030\013 \001(\004\022\024\n\014LastChecksu" + "m\030\014 \001(\r\022\014\n\004Flag\030\r \001(\r\022\027\n\017SystemVariables" + "\030\016 \001(\014\022\027\n\017MasterVariables\030\017 \001(\014\"\316\001\n\rChec" + "kpointMsg\022\017\n\007MsgType\030\001 \002(\005\022\016\n\006NodeID\030\002 \002" + "(\004\022\014\n\004Flag\030\003 \001(\005\022\014\n\004UUID\030\004 \002(\004\022\020\n\010Sequen" + "ce\030\005 \002(\004\022\034\n\024CheckpointInstanceID\030\006 \001(\004\022\020" + "\n\010Checksum\030\007 \001(\r\022\020\n\010FilePath\030\010 \001(\t\022\014\n\004SM" + "ID\030\t \001(\005\022\016\n\006Offset\030\n \001(\004\022\016\n\006Buffer\030\013 \001(\014" + "\"\246\001\n\021AcceptorStateData\022\022\n\nInstanceID\030\001 \002" + "(\004\022\021\n\tPromiseID\030\002 \002(\004\022\025\n\rPromiseNodeID\030\003" + " \002(\004\022\022\n\nAcceptedID\030\004 \002(\004\022\026\n\016AcceptedNode" + "ID\030\005 \002(\004\022\025\n\rAcceptedValue\030\006 \002(\014\022\020\n\010Check" + "sum\030\007 \002(\r\",\n\rPaxosNodeInfo\022\013\n\003Rid\030\001 \002(\004\022" + "\016\n\006Nodeid\030\002 \002(\004\"\\\n\017SystemVariables\022\013\n\003Gi" + "d\030\001 \002(\004\022+\n\nMemberShip\030\002 \003(\0132\027.phxpaxos.P" + "axosNodeInfo\022\017\n\007Version\030\003 \002(\004\"K\n\017MasterV" + "ariables\022\024\n\014MasterNodeid\030\001 \002(\004\022\017\n\007Versio" + "n\030\002 \002(\004\022\021\n\tLeaseTime\030\003 \002(\r", 1026); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "paxos_msg.proto", &protobuf_RegisterTypes); + Header::default_instance_ = new Header(); + PaxosMsg::default_instance_ = new PaxosMsg(); + CheckpointMsg::default_instance_ = new CheckpointMsg(); + AcceptorStateData::default_instance_ = new AcceptorStateData(); + PaxosNodeInfo::default_instance_ = new PaxosNodeInfo(); + SystemVariables::default_instance_ = new SystemVariables(); + MasterVariables::default_instance_ = new MasterVariables(); + Header::default_instance_->InitAsDefaultInstance(); + PaxosMsg::default_instance_->InitAsDefaultInstance(); + CheckpointMsg::default_instance_->InitAsDefaultInstance(); + AcceptorStateData::default_instance_->InitAsDefaultInstance(); + PaxosNodeInfo::default_instance_->InitAsDefaultInstance(); + SystemVariables::default_instance_->InitAsDefaultInstance(); + MasterVariables::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_paxos_5fmsg_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_paxos_5fmsg_2eproto { + StaticDescriptorInitializer_paxos_5fmsg_2eproto() { + protobuf_AddDesc_paxos_5fmsg_2eproto(); + } +} static_descriptor_initializer_paxos_5fmsg_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int Header::kGidFieldNumber; +const int Header::kRidFieldNumber; +const int Header::kCmdidFieldNumber; +const int Header::kVersionFieldNumber; +#endif // !_MSC_VER + +Header::Header() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxpaxos.Header) +} + +void Header::InitAsDefaultInstance() { +} + +Header::Header(const Header& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxpaxos.Header) +} + +void Header::SharedCtor() { + _cached_size_ = 0; + gid_ = GOOGLE_ULONGLONG(0); + rid_ = GOOGLE_ULONGLONG(0); + cmdid_ = 0; + version_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +Header::~Header() { + // @@protoc_insertion_point(destructor:phxpaxos.Header) + SharedDtor(); +} + +void Header::SharedDtor() { + if (this != default_instance_) { + } +} + +void Header::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Header::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Header_descriptor_; +} + +const Header& Header::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_paxos_5fmsg_2eproto(); + return *default_instance_; +} + +Header* Header::default_instance_ = NULL; + +Header* Header::New(::google::protobuf::Arena* arena) const { + Header* n = new Header; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Header::Clear() { +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(gid_, version_); + +#undef ZR_HELPER_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool Header::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxpaxos.Header) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 gid = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &gid_))); + set_has_gid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_rid; + break; + } + + // required uint64 rid = 2; + case 2: { + if (tag == 16) { + parse_rid: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &rid_))); + set_has_rid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_cmdid; + break; + } + + // required int32 cmdid = 3; + case 3: { + if (tag == 24) { + parse_cmdid: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &cmdid_))); + set_has_cmdid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_version; + break; + } + + // optional int32 version = 4; + case 4: { + if (tag == 32) { + parse_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &version_))); + set_has_version(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxpaxos.Header) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxpaxos.Header) + return false; +#undef DO_ +} + +void Header::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxpaxos.Header) + // required uint64 gid = 1; + if (has_gid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->gid(), output); + } + + // required uint64 rid = 2; + if (has_rid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->rid(), output); + } + + // required int32 cmdid = 3; + if (has_cmdid()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->cmdid(), output); + } + + // optional int32 version = 4; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->version(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:phxpaxos.Header) +} + +::google::protobuf::uint8* Header::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxpaxos.Header) + // required uint64 gid = 1; + if (has_gid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->gid(), target); + } + + // required uint64 rid = 2; + if (has_rid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->rid(), target); + } + + // required int32 cmdid = 3; + if (has_cmdid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->cmdid(), target); + } + + // optional int32 version = 4; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->version(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:phxpaxos.Header) + return target; +} + +int Header::RequiredFieldsByteSizeFallback() const { + int total_size = 0; + + if (has_gid()) { + // required uint64 gid = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->gid()); + } + + if (has_rid()) { + // required uint64 rid = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->rid()); + } + + if (has_cmdid()) { + // required int32 cmdid = 3; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->cmdid()); + } + + return total_size; +} +int Header::ByteSize() const { + int total_size = 0; + + if (((_has_bits_[0] & 0x00000007) ^ 0x00000007) == 0) { // All required fields are present. + // required uint64 gid = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->gid()); + + // required uint64 rid = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->rid()); + + // required int32 cmdid = 3; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->cmdid()); + + } else { + total_size += RequiredFieldsByteSizeFallback(); + } + // optional int32 version = 4; + if (has_version()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->version()); + } + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Header::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Header* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Header::MergeFrom(const Header& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_gid()) { + set_gid(from.gid()); + } + if (from.has_rid()) { + set_rid(from.rid()); + } + if (from.has_cmdid()) { + set_cmdid(from.cmdid()); + } + if (from.has_version()) { + set_version(from.version()); + } + } + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void Header::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Header::CopyFrom(const Header& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Header::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void Header::Swap(Header* other) { + if (other == this) return; + InternalSwap(other); +} +void Header::InternalSwap(Header* other) { + std::swap(gid_, other->gid_); + std::swap(rid_, other->rid_); + std::swap(cmdid_, other->cmdid_); + std::swap(version_, other->version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Header::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Header_descriptor_; + metadata.reflection = Header_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Header + +// required uint64 gid = 1; +bool Header::has_gid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void Header::set_has_gid() { + _has_bits_[0] |= 0x00000001u; +} +void Header::clear_has_gid() { + _has_bits_[0] &= ~0x00000001u; +} +void Header::clear_gid() { + gid_ = GOOGLE_ULONGLONG(0); + clear_has_gid(); +} + ::google::protobuf::uint64 Header::gid() const { + // @@protoc_insertion_point(field_get:phxpaxos.Header.gid) + return gid_; +} + void Header::set_gid(::google::protobuf::uint64 value) { + set_has_gid(); + gid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.Header.gid) +} + +// required uint64 rid = 2; +bool Header::has_rid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void Header::set_has_rid() { + _has_bits_[0] |= 0x00000002u; +} +void Header::clear_has_rid() { + _has_bits_[0] &= ~0x00000002u; +} +void Header::clear_rid() { + rid_ = GOOGLE_ULONGLONG(0); + clear_has_rid(); +} + ::google::protobuf::uint64 Header::rid() const { + // @@protoc_insertion_point(field_get:phxpaxos.Header.rid) + return rid_; +} + void Header::set_rid(::google::protobuf::uint64 value) { + set_has_rid(); + rid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.Header.rid) +} + +// required int32 cmdid = 3; +bool Header::has_cmdid() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +void Header::set_has_cmdid() { + _has_bits_[0] |= 0x00000004u; +} +void Header::clear_has_cmdid() { + _has_bits_[0] &= ~0x00000004u; +} +void Header::clear_cmdid() { + cmdid_ = 0; + clear_has_cmdid(); +} + ::google::protobuf::int32 Header::cmdid() const { + // @@protoc_insertion_point(field_get:phxpaxos.Header.cmdid) + return cmdid_; +} + void Header::set_cmdid(::google::protobuf::int32 value) { + set_has_cmdid(); + cmdid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.Header.cmdid) +} + +// optional int32 version = 4; +bool Header::has_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +void Header::set_has_version() { + _has_bits_[0] |= 0x00000008u; +} +void Header::clear_has_version() { + _has_bits_[0] &= ~0x00000008u; +} +void Header::clear_version() { + version_ = 0; + clear_has_version(); +} + ::google::protobuf::int32 Header::version() const { + // @@protoc_insertion_point(field_get:phxpaxos.Header.version) + return version_; +} + void Header::set_version(::google::protobuf::int32 value) { + set_has_version(); + version_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.Header.version) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int PaxosMsg::kMsgTypeFieldNumber; +const int PaxosMsg::kInstanceIDFieldNumber; +const int PaxosMsg::kNodeIDFieldNumber; +const int PaxosMsg::kProposalIDFieldNumber; +const int PaxosMsg::kProposalNodeIDFieldNumber; +const int PaxosMsg::kValueFieldNumber; +const int PaxosMsg::kPreAcceptIDFieldNumber; +const int PaxosMsg::kPreAcceptNodeIDFieldNumber; +const int PaxosMsg::kRejectByPromiseIDFieldNumber; +const int PaxosMsg::kNowInstanceIDFieldNumber; +const int PaxosMsg::kMinChosenInstanceIDFieldNumber; +const int PaxosMsg::kLastChecksumFieldNumber; +const int PaxosMsg::kFlagFieldNumber; +const int PaxosMsg::kSystemVariablesFieldNumber; +const int PaxosMsg::kMasterVariablesFieldNumber; +#endif // !_MSC_VER + +PaxosMsg::PaxosMsg() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxpaxos.PaxosMsg) +} + +void PaxosMsg::InitAsDefaultInstance() { +} + +PaxosMsg::PaxosMsg(const PaxosMsg& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxpaxos.PaxosMsg) +} + +void PaxosMsg::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + msgtype_ = 0; + instanceid_ = GOOGLE_ULONGLONG(0); + nodeid_ = GOOGLE_ULONGLONG(0); + proposalid_ = GOOGLE_ULONGLONG(0); + proposalnodeid_ = GOOGLE_ULONGLONG(0); + value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + preacceptid_ = GOOGLE_ULONGLONG(0); + preacceptnodeid_ = GOOGLE_ULONGLONG(0); + rejectbypromiseid_ = GOOGLE_ULONGLONG(0); + nowinstanceid_ = GOOGLE_ULONGLONG(0); + minchoseninstanceid_ = GOOGLE_ULONGLONG(0); + lastchecksum_ = 0u; + flag_ = 0u; + systemvariables_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + mastervariables_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +PaxosMsg::~PaxosMsg() { + // @@protoc_insertion_point(destructor:phxpaxos.PaxosMsg) + SharedDtor(); +} + +void PaxosMsg::SharedDtor() { + value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + systemvariables_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + mastervariables_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void PaxosMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* PaxosMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return PaxosMsg_descriptor_; +} + +const PaxosMsg& PaxosMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_paxos_5fmsg_2eproto(); + return *default_instance_; +} + +PaxosMsg* PaxosMsg::default_instance_ = NULL; + +PaxosMsg* PaxosMsg::New(::google::protobuf::Arena* arena) const { + PaxosMsg* n = new PaxosMsg; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void PaxosMsg::Clear() { +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + if (_has_bits_[0 / 32] & 255u) { + ZR_(instanceid_, proposalnodeid_); + ZR_(preacceptid_, preacceptnodeid_); + msgtype_ = 0; + if (has_value()) { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + } + if (_has_bits_[8 / 32] & 32512u) { + ZR_(rejectbypromiseid_, minchoseninstanceid_); + lastchecksum_ = 0u; + flag_ = 0u; + if (has_systemvariables()) { + systemvariables_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + if (has_mastervariables()) { + mastervariables_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + } + +#undef ZR_HELPER_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool PaxosMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxpaxos.PaxosMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 MsgType = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &msgtype_))); + set_has_msgtype(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_InstanceID; + break; + } + + // optional uint64 InstanceID = 2; + case 2: { + if (tag == 16) { + parse_InstanceID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &instanceid_))); + set_has_instanceid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_NodeID; + break; + } + + // optional uint64 NodeID = 3; + case 3: { + if (tag == 24) { + parse_NodeID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &nodeid_))); + set_has_nodeid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_ProposalID; + break; + } + + // optional uint64 ProposalID = 4; + case 4: { + if (tag == 32) { + parse_ProposalID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &proposalid_))); + set_has_proposalid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_ProposalNodeID; + break; + } + + // optional uint64 ProposalNodeID = 5; + case 5: { + if (tag == 40) { + parse_ProposalNodeID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &proposalnodeid_))); + set_has_proposalnodeid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_Value; + break; + } + + // optional bytes Value = 6; + case 6: { + if (tag == 50) { + parse_Value: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_value())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(56)) goto parse_PreAcceptID; + break; + } + + // optional uint64 PreAcceptID = 7; + case 7: { + if (tag == 56) { + parse_PreAcceptID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &preacceptid_))); + set_has_preacceptid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(64)) goto parse_PreAcceptNodeID; + break; + } + + // optional uint64 PreAcceptNodeID = 8; + case 8: { + if (tag == 64) { + parse_PreAcceptNodeID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &preacceptnodeid_))); + set_has_preacceptnodeid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(72)) goto parse_RejectByPromiseID; + break; + } + + // optional uint64 RejectByPromiseID = 9; + case 9: { + if (tag == 72) { + parse_RejectByPromiseID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &rejectbypromiseid_))); + set_has_rejectbypromiseid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(80)) goto parse_NowInstanceID; + break; + } + + // optional uint64 NowInstanceID = 10; + case 10: { + if (tag == 80) { + parse_NowInstanceID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &nowinstanceid_))); + set_has_nowinstanceid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(88)) goto parse_MinChosenInstanceID; + break; + } + + // optional uint64 MinChosenInstanceID = 11; + case 11: { + if (tag == 88) { + parse_MinChosenInstanceID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &minchoseninstanceid_))); + set_has_minchoseninstanceid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(96)) goto parse_LastChecksum; + break; + } + + // optional uint32 LastChecksum = 12; + case 12: { + if (tag == 96) { + parse_LastChecksum: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &lastchecksum_))); + set_has_lastchecksum(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(104)) goto parse_Flag; + break; + } + + // optional uint32 Flag = 13; + case 13: { + if (tag == 104) { + parse_Flag: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &flag_))); + set_has_flag(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(114)) goto parse_SystemVariables; + break; + } + + // optional bytes SystemVariables = 14; + case 14: { + if (tag == 114) { + parse_SystemVariables: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_systemvariables())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(122)) goto parse_MasterVariables; + break; + } + + // optional bytes MasterVariables = 15; + case 15: { + if (tag == 122) { + parse_MasterVariables: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_mastervariables())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxpaxos.PaxosMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxpaxos.PaxosMsg) + return false; +#undef DO_ +} + +void PaxosMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxpaxos.PaxosMsg) + // required int32 MsgType = 1; + if (has_msgtype()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->msgtype(), output); + } + + // optional uint64 InstanceID = 2; + if (has_instanceid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->instanceid(), output); + } + + // optional uint64 NodeID = 3; + if (has_nodeid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->nodeid(), output); + } + + // optional uint64 ProposalID = 4; + if (has_proposalid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->proposalid(), output); + } + + // optional uint64 ProposalNodeID = 5; + if (has_proposalnodeid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(5, this->proposalnodeid(), output); + } + + // optional bytes Value = 6; + if (has_value()) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 6, this->value(), output); + } + + // optional uint64 PreAcceptID = 7; + if (has_preacceptid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(7, this->preacceptid(), output); + } + + // optional uint64 PreAcceptNodeID = 8; + if (has_preacceptnodeid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(8, this->preacceptnodeid(), output); + } + + // optional uint64 RejectByPromiseID = 9; + if (has_rejectbypromiseid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(9, this->rejectbypromiseid(), output); + } + + // optional uint64 NowInstanceID = 10; + if (has_nowinstanceid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(10, this->nowinstanceid(), output); + } + + // optional uint64 MinChosenInstanceID = 11; + if (has_minchoseninstanceid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(11, this->minchoseninstanceid(), output); + } + + // optional uint32 LastChecksum = 12; + if (has_lastchecksum()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(12, this->lastchecksum(), output); + } + + // optional uint32 Flag = 13; + if (has_flag()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(13, this->flag(), output); + } + + // optional bytes SystemVariables = 14; + if (has_systemvariables()) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 14, this->systemvariables(), output); + } + + // optional bytes MasterVariables = 15; + if (has_mastervariables()) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 15, this->mastervariables(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:phxpaxos.PaxosMsg) +} + +::google::protobuf::uint8* PaxosMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxpaxos.PaxosMsg) + // required int32 MsgType = 1; + if (has_msgtype()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->msgtype(), target); + } + + // optional uint64 InstanceID = 2; + if (has_instanceid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->instanceid(), target); + } + + // optional uint64 NodeID = 3; + if (has_nodeid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->nodeid(), target); + } + + // optional uint64 ProposalID = 4; + if (has_proposalid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->proposalid(), target); + } + + // optional uint64 ProposalNodeID = 5; + if (has_proposalnodeid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(5, this->proposalnodeid(), target); + } + + // optional bytes Value = 6; + if (has_value()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 6, this->value(), target); + } + + // optional uint64 PreAcceptID = 7; + if (has_preacceptid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(7, this->preacceptid(), target); + } + + // optional uint64 PreAcceptNodeID = 8; + if (has_preacceptnodeid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(8, this->preacceptnodeid(), target); + } + + // optional uint64 RejectByPromiseID = 9; + if (has_rejectbypromiseid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(9, this->rejectbypromiseid(), target); + } + + // optional uint64 NowInstanceID = 10; + if (has_nowinstanceid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(10, this->nowinstanceid(), target); + } + + // optional uint64 MinChosenInstanceID = 11; + if (has_minchoseninstanceid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(11, this->minchoseninstanceid(), target); + } + + // optional uint32 LastChecksum = 12; + if (has_lastchecksum()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(12, this->lastchecksum(), target); + } + + // optional uint32 Flag = 13; + if (has_flag()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(13, this->flag(), target); + } + + // optional bytes SystemVariables = 14; + if (has_systemvariables()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 14, this->systemvariables(), target); + } + + // optional bytes MasterVariables = 15; + if (has_mastervariables()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 15, this->mastervariables(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:phxpaxos.PaxosMsg) + return target; +} + +int PaxosMsg::ByteSize() const { + int total_size = 0; + + // required int32 MsgType = 1; + if (has_msgtype()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->msgtype()); + } + if (_has_bits_[1 / 32] & 254u) { + // optional uint64 InstanceID = 2; + if (has_instanceid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->instanceid()); + } + + // optional uint64 NodeID = 3; + if (has_nodeid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->nodeid()); + } + + // optional uint64 ProposalID = 4; + if (has_proposalid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->proposalid()); + } + + // optional uint64 ProposalNodeID = 5; + if (has_proposalnodeid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->proposalnodeid()); + } + + // optional bytes Value = 6; + if (has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->value()); + } + + // optional uint64 PreAcceptID = 7; + if (has_preacceptid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->preacceptid()); + } + + // optional uint64 PreAcceptNodeID = 8; + if (has_preacceptnodeid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->preacceptnodeid()); + } + + } + if (_has_bits_[8 / 32] & 32512u) { + // optional uint64 RejectByPromiseID = 9; + if (has_rejectbypromiseid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->rejectbypromiseid()); + } + + // optional uint64 NowInstanceID = 10; + if (has_nowinstanceid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->nowinstanceid()); + } + + // optional uint64 MinChosenInstanceID = 11; + if (has_minchoseninstanceid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->minchoseninstanceid()); + } + + // optional uint32 LastChecksum = 12; + if (has_lastchecksum()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->lastchecksum()); + } + + // optional uint32 Flag = 13; + if (has_flag()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->flag()); + } + + // optional bytes SystemVariables = 14; + if (has_systemvariables()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->systemvariables()); + } + + // optional bytes MasterVariables = 15; + if (has_mastervariables()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->mastervariables()); + } + + } + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void PaxosMsg::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const PaxosMsg* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void PaxosMsg::MergeFrom(const PaxosMsg& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_msgtype()) { + set_msgtype(from.msgtype()); + } + if (from.has_instanceid()) { + set_instanceid(from.instanceid()); + } + if (from.has_nodeid()) { + set_nodeid(from.nodeid()); + } + if (from.has_proposalid()) { + set_proposalid(from.proposalid()); + } + if (from.has_proposalnodeid()) { + set_proposalnodeid(from.proposalnodeid()); + } + if (from.has_value()) { + set_has_value(); + value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_); + } + if (from.has_preacceptid()) { + set_preacceptid(from.preacceptid()); + } + if (from.has_preacceptnodeid()) { + set_preacceptnodeid(from.preacceptnodeid()); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_rejectbypromiseid()) { + set_rejectbypromiseid(from.rejectbypromiseid()); + } + if (from.has_nowinstanceid()) { + set_nowinstanceid(from.nowinstanceid()); + } + if (from.has_minchoseninstanceid()) { + set_minchoseninstanceid(from.minchoseninstanceid()); + } + if (from.has_lastchecksum()) { + set_lastchecksum(from.lastchecksum()); + } + if (from.has_flag()) { + set_flag(from.flag()); + } + if (from.has_systemvariables()) { + set_has_systemvariables(); + systemvariables_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.systemvariables_); + } + if (from.has_mastervariables()) { + set_has_mastervariables(); + mastervariables_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.mastervariables_); + } + } + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void PaxosMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void PaxosMsg::CopyFrom(const PaxosMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool PaxosMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + + return true; +} + +void PaxosMsg::Swap(PaxosMsg* other) { + if (other == this) return; + InternalSwap(other); +} +void PaxosMsg::InternalSwap(PaxosMsg* other) { + std::swap(msgtype_, other->msgtype_); + std::swap(instanceid_, other->instanceid_); + std::swap(nodeid_, other->nodeid_); + std::swap(proposalid_, other->proposalid_); + std::swap(proposalnodeid_, other->proposalnodeid_); + value_.Swap(&other->value_); + std::swap(preacceptid_, other->preacceptid_); + std::swap(preacceptnodeid_, other->preacceptnodeid_); + std::swap(rejectbypromiseid_, other->rejectbypromiseid_); + std::swap(nowinstanceid_, other->nowinstanceid_); + std::swap(minchoseninstanceid_, other->minchoseninstanceid_); + std::swap(lastchecksum_, other->lastchecksum_); + std::swap(flag_, other->flag_); + systemvariables_.Swap(&other->systemvariables_); + mastervariables_.Swap(&other->mastervariables_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata PaxosMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = PaxosMsg_descriptor_; + metadata.reflection = PaxosMsg_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// PaxosMsg + +// required int32 MsgType = 1; +bool PaxosMsg::has_msgtype() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void PaxosMsg::set_has_msgtype() { + _has_bits_[0] |= 0x00000001u; +} +void PaxosMsg::clear_has_msgtype() { + _has_bits_[0] &= ~0x00000001u; +} +void PaxosMsg::clear_msgtype() { + msgtype_ = 0; + clear_has_msgtype(); +} + ::google::protobuf::int32 PaxosMsg::msgtype() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.MsgType) + return msgtype_; +} + void PaxosMsg::set_msgtype(::google::protobuf::int32 value) { + set_has_msgtype(); + msgtype_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.MsgType) +} + +// optional uint64 InstanceID = 2; +bool PaxosMsg::has_instanceid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void PaxosMsg::set_has_instanceid() { + _has_bits_[0] |= 0x00000002u; +} +void PaxosMsg::clear_has_instanceid() { + _has_bits_[0] &= ~0x00000002u; +} +void PaxosMsg::clear_instanceid() { + instanceid_ = GOOGLE_ULONGLONG(0); + clear_has_instanceid(); +} + ::google::protobuf::uint64 PaxosMsg::instanceid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.InstanceID) + return instanceid_; +} + void PaxosMsg::set_instanceid(::google::protobuf::uint64 value) { + set_has_instanceid(); + instanceid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.InstanceID) +} + +// optional uint64 NodeID = 3; +bool PaxosMsg::has_nodeid() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +void PaxosMsg::set_has_nodeid() { + _has_bits_[0] |= 0x00000004u; +} +void PaxosMsg::clear_has_nodeid() { + _has_bits_[0] &= ~0x00000004u; +} +void PaxosMsg::clear_nodeid() { + nodeid_ = GOOGLE_ULONGLONG(0); + clear_has_nodeid(); +} + ::google::protobuf::uint64 PaxosMsg::nodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.NodeID) + return nodeid_; +} + void PaxosMsg::set_nodeid(::google::protobuf::uint64 value) { + set_has_nodeid(); + nodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.NodeID) +} + +// optional uint64 ProposalID = 4; +bool PaxosMsg::has_proposalid() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +void PaxosMsg::set_has_proposalid() { + _has_bits_[0] |= 0x00000008u; +} +void PaxosMsg::clear_has_proposalid() { + _has_bits_[0] &= ~0x00000008u; +} +void PaxosMsg::clear_proposalid() { + proposalid_ = GOOGLE_ULONGLONG(0); + clear_has_proposalid(); +} + ::google::protobuf::uint64 PaxosMsg::proposalid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.ProposalID) + return proposalid_; +} + void PaxosMsg::set_proposalid(::google::protobuf::uint64 value) { + set_has_proposalid(); + proposalid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.ProposalID) +} + +// optional uint64 ProposalNodeID = 5; +bool PaxosMsg::has_proposalnodeid() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +void PaxosMsg::set_has_proposalnodeid() { + _has_bits_[0] |= 0x00000010u; +} +void PaxosMsg::clear_has_proposalnodeid() { + _has_bits_[0] &= ~0x00000010u; +} +void PaxosMsg::clear_proposalnodeid() { + proposalnodeid_ = GOOGLE_ULONGLONG(0); + clear_has_proposalnodeid(); +} + ::google::protobuf::uint64 PaxosMsg::proposalnodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.ProposalNodeID) + return proposalnodeid_; +} + void PaxosMsg::set_proposalnodeid(::google::protobuf::uint64 value) { + set_has_proposalnodeid(); + proposalnodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.ProposalNodeID) +} + +// optional bytes Value = 6; +bool PaxosMsg::has_value() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +void PaxosMsg::set_has_value() { + _has_bits_[0] |= 0x00000020u; +} +void PaxosMsg::clear_has_value() { + _has_bits_[0] &= ~0x00000020u; +} +void PaxosMsg::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_value(); +} + const ::std::string& PaxosMsg::value() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.Value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void PaxosMsg::set_value(const ::std::string& value) { + set_has_value(); + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.Value) +} + void PaxosMsg::set_value(const char* value) { + set_has_value(); + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.PaxosMsg.Value) +} + void PaxosMsg::set_value(const void* value, size_t size) { + set_has_value(); + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.PaxosMsg.Value) +} + ::std::string* PaxosMsg::mutable_value() { + set_has_value(); + // @@protoc_insertion_point(field_mutable:phxpaxos.PaxosMsg.Value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* PaxosMsg::release_value() { + clear_has_value(); + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void PaxosMsg::set_allocated_value(::std::string* value) { + if (value != NULL) { + set_has_value(); + } else { + clear_has_value(); + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.PaxosMsg.Value) +} + +// optional uint64 PreAcceptID = 7; +bool PaxosMsg::has_preacceptid() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +void PaxosMsg::set_has_preacceptid() { + _has_bits_[0] |= 0x00000040u; +} +void PaxosMsg::clear_has_preacceptid() { + _has_bits_[0] &= ~0x00000040u; +} +void PaxosMsg::clear_preacceptid() { + preacceptid_ = GOOGLE_ULONGLONG(0); + clear_has_preacceptid(); +} + ::google::protobuf::uint64 PaxosMsg::preacceptid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.PreAcceptID) + return preacceptid_; +} + void PaxosMsg::set_preacceptid(::google::protobuf::uint64 value) { + set_has_preacceptid(); + preacceptid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.PreAcceptID) +} + +// optional uint64 PreAcceptNodeID = 8; +bool PaxosMsg::has_preacceptnodeid() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +void PaxosMsg::set_has_preacceptnodeid() { + _has_bits_[0] |= 0x00000080u; +} +void PaxosMsg::clear_has_preacceptnodeid() { + _has_bits_[0] &= ~0x00000080u; +} +void PaxosMsg::clear_preacceptnodeid() { + preacceptnodeid_ = GOOGLE_ULONGLONG(0); + clear_has_preacceptnodeid(); +} + ::google::protobuf::uint64 PaxosMsg::preacceptnodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.PreAcceptNodeID) + return preacceptnodeid_; +} + void PaxosMsg::set_preacceptnodeid(::google::protobuf::uint64 value) { + set_has_preacceptnodeid(); + preacceptnodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.PreAcceptNodeID) +} + +// optional uint64 RejectByPromiseID = 9; +bool PaxosMsg::has_rejectbypromiseid() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +void PaxosMsg::set_has_rejectbypromiseid() { + _has_bits_[0] |= 0x00000100u; +} +void PaxosMsg::clear_has_rejectbypromiseid() { + _has_bits_[0] &= ~0x00000100u; +} +void PaxosMsg::clear_rejectbypromiseid() { + rejectbypromiseid_ = GOOGLE_ULONGLONG(0); + clear_has_rejectbypromiseid(); +} + ::google::protobuf::uint64 PaxosMsg::rejectbypromiseid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.RejectByPromiseID) + return rejectbypromiseid_; +} + void PaxosMsg::set_rejectbypromiseid(::google::protobuf::uint64 value) { + set_has_rejectbypromiseid(); + rejectbypromiseid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.RejectByPromiseID) +} + +// optional uint64 NowInstanceID = 10; +bool PaxosMsg::has_nowinstanceid() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +void PaxosMsg::set_has_nowinstanceid() { + _has_bits_[0] |= 0x00000200u; +} +void PaxosMsg::clear_has_nowinstanceid() { + _has_bits_[0] &= ~0x00000200u; +} +void PaxosMsg::clear_nowinstanceid() { + nowinstanceid_ = GOOGLE_ULONGLONG(0); + clear_has_nowinstanceid(); +} + ::google::protobuf::uint64 PaxosMsg::nowinstanceid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.NowInstanceID) + return nowinstanceid_; +} + void PaxosMsg::set_nowinstanceid(::google::protobuf::uint64 value) { + set_has_nowinstanceid(); + nowinstanceid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.NowInstanceID) +} + +// optional uint64 MinChosenInstanceID = 11; +bool PaxosMsg::has_minchoseninstanceid() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +void PaxosMsg::set_has_minchoseninstanceid() { + _has_bits_[0] |= 0x00000400u; +} +void PaxosMsg::clear_has_minchoseninstanceid() { + _has_bits_[0] &= ~0x00000400u; +} +void PaxosMsg::clear_minchoseninstanceid() { + minchoseninstanceid_ = GOOGLE_ULONGLONG(0); + clear_has_minchoseninstanceid(); +} + ::google::protobuf::uint64 PaxosMsg::minchoseninstanceid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.MinChosenInstanceID) + return minchoseninstanceid_; +} + void PaxosMsg::set_minchoseninstanceid(::google::protobuf::uint64 value) { + set_has_minchoseninstanceid(); + minchoseninstanceid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.MinChosenInstanceID) +} + +// optional uint32 LastChecksum = 12; +bool PaxosMsg::has_lastchecksum() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +void PaxosMsg::set_has_lastchecksum() { + _has_bits_[0] |= 0x00000800u; +} +void PaxosMsg::clear_has_lastchecksum() { + _has_bits_[0] &= ~0x00000800u; +} +void PaxosMsg::clear_lastchecksum() { + lastchecksum_ = 0u; + clear_has_lastchecksum(); +} + ::google::protobuf::uint32 PaxosMsg::lastchecksum() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.LastChecksum) + return lastchecksum_; +} + void PaxosMsg::set_lastchecksum(::google::protobuf::uint32 value) { + set_has_lastchecksum(); + lastchecksum_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.LastChecksum) +} + +// optional uint32 Flag = 13; +bool PaxosMsg::has_flag() const { + return (_has_bits_[0] & 0x00001000u) != 0; +} +void PaxosMsg::set_has_flag() { + _has_bits_[0] |= 0x00001000u; +} +void PaxosMsg::clear_has_flag() { + _has_bits_[0] &= ~0x00001000u; +} +void PaxosMsg::clear_flag() { + flag_ = 0u; + clear_has_flag(); +} + ::google::protobuf::uint32 PaxosMsg::flag() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.Flag) + return flag_; +} + void PaxosMsg::set_flag(::google::protobuf::uint32 value) { + set_has_flag(); + flag_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.Flag) +} + +// optional bytes SystemVariables = 14; +bool PaxosMsg::has_systemvariables() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +void PaxosMsg::set_has_systemvariables() { + _has_bits_[0] |= 0x00002000u; +} +void PaxosMsg::clear_has_systemvariables() { + _has_bits_[0] &= ~0x00002000u; +} +void PaxosMsg::clear_systemvariables() { + systemvariables_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_systemvariables(); +} + const ::std::string& PaxosMsg::systemvariables() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.SystemVariables) + return systemvariables_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void PaxosMsg::set_systemvariables(const ::std::string& value) { + set_has_systemvariables(); + systemvariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.SystemVariables) +} + void PaxosMsg::set_systemvariables(const char* value) { + set_has_systemvariables(); + systemvariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.PaxosMsg.SystemVariables) +} + void PaxosMsg::set_systemvariables(const void* value, size_t size) { + set_has_systemvariables(); + systemvariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.PaxosMsg.SystemVariables) +} + ::std::string* PaxosMsg::mutable_systemvariables() { + set_has_systemvariables(); + // @@protoc_insertion_point(field_mutable:phxpaxos.PaxosMsg.SystemVariables) + return systemvariables_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* PaxosMsg::release_systemvariables() { + clear_has_systemvariables(); + return systemvariables_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void PaxosMsg::set_allocated_systemvariables(::std::string* systemvariables) { + if (systemvariables != NULL) { + set_has_systemvariables(); + } else { + clear_has_systemvariables(); + } + systemvariables_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), systemvariables); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.PaxosMsg.SystemVariables) +} + +// optional bytes MasterVariables = 15; +bool PaxosMsg::has_mastervariables() const { + return (_has_bits_[0] & 0x00004000u) != 0; +} +void PaxosMsg::set_has_mastervariables() { + _has_bits_[0] |= 0x00004000u; +} +void PaxosMsg::clear_has_mastervariables() { + _has_bits_[0] &= ~0x00004000u; +} +void PaxosMsg::clear_mastervariables() { + mastervariables_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_mastervariables(); +} + const ::std::string& PaxosMsg::mastervariables() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.MasterVariables) + return mastervariables_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void PaxosMsg::set_mastervariables(const ::std::string& value) { + set_has_mastervariables(); + mastervariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.MasterVariables) +} + void PaxosMsg::set_mastervariables(const char* value) { + set_has_mastervariables(); + mastervariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.PaxosMsg.MasterVariables) +} + void PaxosMsg::set_mastervariables(const void* value, size_t size) { + set_has_mastervariables(); + mastervariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.PaxosMsg.MasterVariables) +} + ::std::string* PaxosMsg::mutable_mastervariables() { + set_has_mastervariables(); + // @@protoc_insertion_point(field_mutable:phxpaxos.PaxosMsg.MasterVariables) + return mastervariables_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* PaxosMsg::release_mastervariables() { + clear_has_mastervariables(); + return mastervariables_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void PaxosMsg::set_allocated_mastervariables(::std::string* mastervariables) { + if (mastervariables != NULL) { + set_has_mastervariables(); + } else { + clear_has_mastervariables(); + } + mastervariables_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), mastervariables); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.PaxosMsg.MasterVariables) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int CheckpointMsg::kMsgTypeFieldNumber; +const int CheckpointMsg::kNodeIDFieldNumber; +const int CheckpointMsg::kFlagFieldNumber; +const int CheckpointMsg::kUUIDFieldNumber; +const int CheckpointMsg::kSequenceFieldNumber; +const int CheckpointMsg::kCheckpointInstanceIDFieldNumber; +const int CheckpointMsg::kChecksumFieldNumber; +const int CheckpointMsg::kFilePathFieldNumber; +const int CheckpointMsg::kSMIDFieldNumber; +const int CheckpointMsg::kOffsetFieldNumber; +const int CheckpointMsg::kBufferFieldNumber; +#endif // !_MSC_VER + +CheckpointMsg::CheckpointMsg() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxpaxos.CheckpointMsg) +} + +void CheckpointMsg::InitAsDefaultInstance() { +} + +CheckpointMsg::CheckpointMsg(const CheckpointMsg& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxpaxos.CheckpointMsg) +} + +void CheckpointMsg::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + msgtype_ = 0; + nodeid_ = GOOGLE_ULONGLONG(0); + flag_ = 0; + uuid_ = GOOGLE_ULONGLONG(0); + sequence_ = GOOGLE_ULONGLONG(0); + checkpointinstanceid_ = GOOGLE_ULONGLONG(0); + checksum_ = 0u; + filepath_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + smid_ = 0; + offset_ = GOOGLE_ULONGLONG(0); + buffer_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +CheckpointMsg::~CheckpointMsg() { + // @@protoc_insertion_point(destructor:phxpaxos.CheckpointMsg) + SharedDtor(); +} + +void CheckpointMsg::SharedDtor() { + filepath_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + buffer_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void CheckpointMsg::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* CheckpointMsg::descriptor() { + protobuf_AssignDescriptorsOnce(); + return CheckpointMsg_descriptor_; +} + +const CheckpointMsg& CheckpointMsg::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_paxos_5fmsg_2eproto(); + return *default_instance_; +} + +CheckpointMsg* CheckpointMsg::default_instance_ = NULL; + +CheckpointMsg* CheckpointMsg::New(::google::protobuf::Arena* arena) const { + CheckpointMsg* n = new CheckpointMsg; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void CheckpointMsg::Clear() { +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + if (_has_bits_[0 / 32] & 255u) { + ZR_(nodeid_, checkpointinstanceid_); + checksum_ = 0u; + if (has_filepath()) { + filepath_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + } + if (_has_bits_[8 / 32] & 1792u) { + ZR_(smid_, offset_); + if (has_buffer()) { + buffer_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + } + +#undef ZR_HELPER_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool CheckpointMsg::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxpaxos.CheckpointMsg) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required int32 MsgType = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &msgtype_))); + set_has_msgtype(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_NodeID; + break; + } + + // required uint64 NodeID = 2; + case 2: { + if (tag == 16) { + parse_NodeID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &nodeid_))); + set_has_nodeid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_Flag; + break; + } + + // optional int32 Flag = 3; + case 3: { + if (tag == 24) { + parse_Flag: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &flag_))); + set_has_flag(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_UUID; + break; + } + + // required uint64 UUID = 4; + case 4: { + if (tag == 32) { + parse_UUID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &uuid_))); + set_has_uuid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_Sequence; + break; + } + + // required uint64 Sequence = 5; + case 5: { + if (tag == 40) { + parse_Sequence: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &sequence_))); + set_has_sequence(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(48)) goto parse_CheckpointInstanceID; + break; + } + + // optional uint64 CheckpointInstanceID = 6; + case 6: { + if (tag == 48) { + parse_CheckpointInstanceID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &checkpointinstanceid_))); + set_has_checkpointinstanceid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(56)) goto parse_Checksum; + break; + } + + // optional uint32 Checksum = 7; + case 7: { + if (tag == 56) { + parse_Checksum: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &checksum_))); + set_has_checksum(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(66)) goto parse_FilePath; + break; + } + + // optional string FilePath = 8; + case 8: { + if (tag == 66) { + parse_FilePath: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_filepath())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->filepath().data(), this->filepath().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "phxpaxos.CheckpointMsg.FilePath"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(72)) goto parse_SMID; + break; + } + + // optional int32 SMID = 9; + case 9: { + if (tag == 72) { + parse_SMID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &smid_))); + set_has_smid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(80)) goto parse_Offset; + break; + } + + // optional uint64 Offset = 10; + case 10: { + if (tag == 80) { + parse_Offset: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &offset_))); + set_has_offset(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(90)) goto parse_Buffer; + break; + } + + // optional bytes Buffer = 11; + case 11: { + if (tag == 90) { + parse_Buffer: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_buffer())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxpaxos.CheckpointMsg) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxpaxos.CheckpointMsg) + return false; +#undef DO_ +} + +void CheckpointMsg::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxpaxos.CheckpointMsg) + // required int32 MsgType = 1; + if (has_msgtype()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->msgtype(), output); + } + + // required uint64 NodeID = 2; + if (has_nodeid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->nodeid(), output); + } + + // optional int32 Flag = 3; + if (has_flag()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->flag(), output); + } + + // required uint64 UUID = 4; + if (has_uuid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->uuid(), output); + } + + // required uint64 Sequence = 5; + if (has_sequence()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(5, this->sequence(), output); + } + + // optional uint64 CheckpointInstanceID = 6; + if (has_checkpointinstanceid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(6, this->checkpointinstanceid(), output); + } + + // optional uint32 Checksum = 7; + if (has_checksum()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->checksum(), output); + } + + // optional string FilePath = 8; + if (has_filepath()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->filepath().data(), this->filepath().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "phxpaxos.CheckpointMsg.FilePath"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 8, this->filepath(), output); + } + + // optional int32 SMID = 9; + if (has_smid()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->smid(), output); + } + + // optional uint64 Offset = 10; + if (has_offset()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(10, this->offset(), output); + } + + // optional bytes Buffer = 11; + if (has_buffer()) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 11, this->buffer(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:phxpaxos.CheckpointMsg) +} + +::google::protobuf::uint8* CheckpointMsg::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxpaxos.CheckpointMsg) + // required int32 MsgType = 1; + if (has_msgtype()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->msgtype(), target); + } + + // required uint64 NodeID = 2; + if (has_nodeid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->nodeid(), target); + } + + // optional int32 Flag = 3; + if (has_flag()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->flag(), target); + } + + // required uint64 UUID = 4; + if (has_uuid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->uuid(), target); + } + + // required uint64 Sequence = 5; + if (has_sequence()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(5, this->sequence(), target); + } + + // optional uint64 CheckpointInstanceID = 6; + if (has_checkpointinstanceid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(6, this->checkpointinstanceid(), target); + } + + // optional uint32 Checksum = 7; + if (has_checksum()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(7, this->checksum(), target); + } + + // optional string FilePath = 8; + if (has_filepath()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->filepath().data(), this->filepath().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "phxpaxos.CheckpointMsg.FilePath"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 8, this->filepath(), target); + } + + // optional int32 SMID = 9; + if (has_smid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(9, this->smid(), target); + } + + // optional uint64 Offset = 10; + if (has_offset()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(10, this->offset(), target); + } + + // optional bytes Buffer = 11; + if (has_buffer()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 11, this->buffer(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:phxpaxos.CheckpointMsg) + return target; +} + +int CheckpointMsg::RequiredFieldsByteSizeFallback() const { + int total_size = 0; + + if (has_msgtype()) { + // required int32 MsgType = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->msgtype()); + } + + if (has_nodeid()) { + // required uint64 NodeID = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->nodeid()); + } + + if (has_uuid()) { + // required uint64 UUID = 4; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->uuid()); + } + + if (has_sequence()) { + // required uint64 Sequence = 5; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->sequence()); + } + + return total_size; +} +int CheckpointMsg::ByteSize() const { + int total_size = 0; + + if (((_has_bits_[0] & 0x0000001b) ^ 0x0000001b) == 0) { // All required fields are present. + // required int32 MsgType = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->msgtype()); + + // required uint64 NodeID = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->nodeid()); + + // required uint64 UUID = 4; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->uuid()); + + // required uint64 Sequence = 5; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->sequence()); + + } else { + total_size += RequiredFieldsByteSizeFallback(); + } + if (_has_bits_[2 / 32] & 228u) { + // optional int32 Flag = 3; + if (has_flag()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->flag()); + } + + // optional uint64 CheckpointInstanceID = 6; + if (has_checkpointinstanceid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->checkpointinstanceid()); + } + + // optional uint32 Checksum = 7; + if (has_checksum()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->checksum()); + } + + // optional string FilePath = 8; + if (has_filepath()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->filepath()); + } + + } + if (_has_bits_[8 / 32] & 1792u) { + // optional int32 SMID = 9; + if (has_smid()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->smid()); + } + + // optional uint64 Offset = 10; + if (has_offset()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->offset()); + } + + // optional bytes Buffer = 11; + if (has_buffer()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->buffer()); + } + + } + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void CheckpointMsg::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const CheckpointMsg* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void CheckpointMsg::MergeFrom(const CheckpointMsg& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_msgtype()) { + set_msgtype(from.msgtype()); + } + if (from.has_nodeid()) { + set_nodeid(from.nodeid()); + } + if (from.has_flag()) { + set_flag(from.flag()); + } + if (from.has_uuid()) { + set_uuid(from.uuid()); + } + if (from.has_sequence()) { + set_sequence(from.sequence()); + } + if (from.has_checkpointinstanceid()) { + set_checkpointinstanceid(from.checkpointinstanceid()); + } + if (from.has_checksum()) { + set_checksum(from.checksum()); + } + if (from.has_filepath()) { + set_has_filepath(); + filepath_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.filepath_); + } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_smid()) { + set_smid(from.smid()); + } + if (from.has_offset()) { + set_offset(from.offset()); + } + if (from.has_buffer()) { + set_has_buffer(); + buffer_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.buffer_); + } + } + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void CheckpointMsg::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void CheckpointMsg::CopyFrom(const CheckpointMsg& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool CheckpointMsg::IsInitialized() const { + if ((_has_bits_[0] & 0x0000001b) != 0x0000001b) return false; + + return true; +} + +void CheckpointMsg::Swap(CheckpointMsg* other) { + if (other == this) return; + InternalSwap(other); +} +void CheckpointMsg::InternalSwap(CheckpointMsg* other) { + std::swap(msgtype_, other->msgtype_); + std::swap(nodeid_, other->nodeid_); + std::swap(flag_, other->flag_); + std::swap(uuid_, other->uuid_); + std::swap(sequence_, other->sequence_); + std::swap(checkpointinstanceid_, other->checkpointinstanceid_); + std::swap(checksum_, other->checksum_); + filepath_.Swap(&other->filepath_); + std::swap(smid_, other->smid_); + std::swap(offset_, other->offset_); + buffer_.Swap(&other->buffer_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata CheckpointMsg::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = CheckpointMsg_descriptor_; + metadata.reflection = CheckpointMsg_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// CheckpointMsg + +// required int32 MsgType = 1; +bool CheckpointMsg::has_msgtype() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void CheckpointMsg::set_has_msgtype() { + _has_bits_[0] |= 0x00000001u; +} +void CheckpointMsg::clear_has_msgtype() { + _has_bits_[0] &= ~0x00000001u; +} +void CheckpointMsg::clear_msgtype() { + msgtype_ = 0; + clear_has_msgtype(); +} + ::google::protobuf::int32 CheckpointMsg::msgtype() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.MsgType) + return msgtype_; +} + void CheckpointMsg::set_msgtype(::google::protobuf::int32 value) { + set_has_msgtype(); + msgtype_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.MsgType) +} + +// required uint64 NodeID = 2; +bool CheckpointMsg::has_nodeid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void CheckpointMsg::set_has_nodeid() { + _has_bits_[0] |= 0x00000002u; +} +void CheckpointMsg::clear_has_nodeid() { + _has_bits_[0] &= ~0x00000002u; +} +void CheckpointMsg::clear_nodeid() { + nodeid_ = GOOGLE_ULONGLONG(0); + clear_has_nodeid(); +} + ::google::protobuf::uint64 CheckpointMsg::nodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.NodeID) + return nodeid_; +} + void CheckpointMsg::set_nodeid(::google::protobuf::uint64 value) { + set_has_nodeid(); + nodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.NodeID) +} + +// optional int32 Flag = 3; +bool CheckpointMsg::has_flag() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +void CheckpointMsg::set_has_flag() { + _has_bits_[0] |= 0x00000004u; +} +void CheckpointMsg::clear_has_flag() { + _has_bits_[0] &= ~0x00000004u; +} +void CheckpointMsg::clear_flag() { + flag_ = 0; + clear_has_flag(); +} + ::google::protobuf::int32 CheckpointMsg::flag() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.Flag) + return flag_; +} + void CheckpointMsg::set_flag(::google::protobuf::int32 value) { + set_has_flag(); + flag_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.Flag) +} + +// required uint64 UUID = 4; +bool CheckpointMsg::has_uuid() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +void CheckpointMsg::set_has_uuid() { + _has_bits_[0] |= 0x00000008u; +} +void CheckpointMsg::clear_has_uuid() { + _has_bits_[0] &= ~0x00000008u; +} +void CheckpointMsg::clear_uuid() { + uuid_ = GOOGLE_ULONGLONG(0); + clear_has_uuid(); +} + ::google::protobuf::uint64 CheckpointMsg::uuid() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.UUID) + return uuid_; +} + void CheckpointMsg::set_uuid(::google::protobuf::uint64 value) { + set_has_uuid(); + uuid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.UUID) +} + +// required uint64 Sequence = 5; +bool CheckpointMsg::has_sequence() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +void CheckpointMsg::set_has_sequence() { + _has_bits_[0] |= 0x00000010u; +} +void CheckpointMsg::clear_has_sequence() { + _has_bits_[0] &= ~0x00000010u; +} +void CheckpointMsg::clear_sequence() { + sequence_ = GOOGLE_ULONGLONG(0); + clear_has_sequence(); +} + ::google::protobuf::uint64 CheckpointMsg::sequence() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.Sequence) + return sequence_; +} + void CheckpointMsg::set_sequence(::google::protobuf::uint64 value) { + set_has_sequence(); + sequence_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.Sequence) +} + +// optional uint64 CheckpointInstanceID = 6; +bool CheckpointMsg::has_checkpointinstanceid() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +void CheckpointMsg::set_has_checkpointinstanceid() { + _has_bits_[0] |= 0x00000020u; +} +void CheckpointMsg::clear_has_checkpointinstanceid() { + _has_bits_[0] &= ~0x00000020u; +} +void CheckpointMsg::clear_checkpointinstanceid() { + checkpointinstanceid_ = GOOGLE_ULONGLONG(0); + clear_has_checkpointinstanceid(); +} + ::google::protobuf::uint64 CheckpointMsg::checkpointinstanceid() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.CheckpointInstanceID) + return checkpointinstanceid_; +} + void CheckpointMsg::set_checkpointinstanceid(::google::protobuf::uint64 value) { + set_has_checkpointinstanceid(); + checkpointinstanceid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.CheckpointInstanceID) +} + +// optional uint32 Checksum = 7; +bool CheckpointMsg::has_checksum() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +void CheckpointMsg::set_has_checksum() { + _has_bits_[0] |= 0x00000040u; +} +void CheckpointMsg::clear_has_checksum() { + _has_bits_[0] &= ~0x00000040u; +} +void CheckpointMsg::clear_checksum() { + checksum_ = 0u; + clear_has_checksum(); +} + ::google::protobuf::uint32 CheckpointMsg::checksum() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.Checksum) + return checksum_; +} + void CheckpointMsg::set_checksum(::google::protobuf::uint32 value) { + set_has_checksum(); + checksum_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.Checksum) +} + +// optional string FilePath = 8; +bool CheckpointMsg::has_filepath() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +void CheckpointMsg::set_has_filepath() { + _has_bits_[0] |= 0x00000080u; +} +void CheckpointMsg::clear_has_filepath() { + _has_bits_[0] &= ~0x00000080u; +} +void CheckpointMsg::clear_filepath() { + filepath_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_filepath(); +} + const ::std::string& CheckpointMsg::filepath() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.FilePath) + return filepath_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CheckpointMsg::set_filepath(const ::std::string& value) { + set_has_filepath(); + filepath_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.FilePath) +} + void CheckpointMsg::set_filepath(const char* value) { + set_has_filepath(); + filepath_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.CheckpointMsg.FilePath) +} + void CheckpointMsg::set_filepath(const char* value, size_t size) { + set_has_filepath(); + filepath_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.CheckpointMsg.FilePath) +} + ::std::string* CheckpointMsg::mutable_filepath() { + set_has_filepath(); + // @@protoc_insertion_point(field_mutable:phxpaxos.CheckpointMsg.FilePath) + return filepath_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* CheckpointMsg::release_filepath() { + clear_has_filepath(); + return filepath_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CheckpointMsg::set_allocated_filepath(::std::string* filepath) { + if (filepath != NULL) { + set_has_filepath(); + } else { + clear_has_filepath(); + } + filepath_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), filepath); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.CheckpointMsg.FilePath) +} + +// optional int32 SMID = 9; +bool CheckpointMsg::has_smid() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +void CheckpointMsg::set_has_smid() { + _has_bits_[0] |= 0x00000100u; +} +void CheckpointMsg::clear_has_smid() { + _has_bits_[0] &= ~0x00000100u; +} +void CheckpointMsg::clear_smid() { + smid_ = 0; + clear_has_smid(); +} + ::google::protobuf::int32 CheckpointMsg::smid() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.SMID) + return smid_; +} + void CheckpointMsg::set_smid(::google::protobuf::int32 value) { + set_has_smid(); + smid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.SMID) +} + +// optional uint64 Offset = 10; +bool CheckpointMsg::has_offset() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +void CheckpointMsg::set_has_offset() { + _has_bits_[0] |= 0x00000200u; +} +void CheckpointMsg::clear_has_offset() { + _has_bits_[0] &= ~0x00000200u; +} +void CheckpointMsg::clear_offset() { + offset_ = GOOGLE_ULONGLONG(0); + clear_has_offset(); +} + ::google::protobuf::uint64 CheckpointMsg::offset() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.Offset) + return offset_; +} + void CheckpointMsg::set_offset(::google::protobuf::uint64 value) { + set_has_offset(); + offset_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.Offset) +} + +// optional bytes Buffer = 11; +bool CheckpointMsg::has_buffer() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +void CheckpointMsg::set_has_buffer() { + _has_bits_[0] |= 0x00000400u; +} +void CheckpointMsg::clear_has_buffer() { + _has_bits_[0] &= ~0x00000400u; +} +void CheckpointMsg::clear_buffer() { + buffer_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_buffer(); +} + const ::std::string& CheckpointMsg::buffer() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.Buffer) + return buffer_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CheckpointMsg::set_buffer(const ::std::string& value) { + set_has_buffer(); + buffer_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.Buffer) +} + void CheckpointMsg::set_buffer(const char* value) { + set_has_buffer(); + buffer_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.CheckpointMsg.Buffer) +} + void CheckpointMsg::set_buffer(const void* value, size_t size) { + set_has_buffer(); + buffer_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.CheckpointMsg.Buffer) +} + ::std::string* CheckpointMsg::mutable_buffer() { + set_has_buffer(); + // @@protoc_insertion_point(field_mutable:phxpaxos.CheckpointMsg.Buffer) + return buffer_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* CheckpointMsg::release_buffer() { + clear_has_buffer(); + return buffer_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void CheckpointMsg::set_allocated_buffer(::std::string* buffer) { + if (buffer != NULL) { + set_has_buffer(); + } else { + clear_has_buffer(); + } + buffer_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), buffer); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.CheckpointMsg.Buffer) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int AcceptorStateData::kInstanceIDFieldNumber; +const int AcceptorStateData::kPromiseIDFieldNumber; +const int AcceptorStateData::kPromiseNodeIDFieldNumber; +const int AcceptorStateData::kAcceptedIDFieldNumber; +const int AcceptorStateData::kAcceptedNodeIDFieldNumber; +const int AcceptorStateData::kAcceptedValueFieldNumber; +const int AcceptorStateData::kChecksumFieldNumber; +#endif // !_MSC_VER + +AcceptorStateData::AcceptorStateData() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxpaxos.AcceptorStateData) +} + +void AcceptorStateData::InitAsDefaultInstance() { +} + +AcceptorStateData::AcceptorStateData(const AcceptorStateData& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxpaxos.AcceptorStateData) +} + +void AcceptorStateData::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + instanceid_ = GOOGLE_ULONGLONG(0); + promiseid_ = GOOGLE_ULONGLONG(0); + promisenodeid_ = GOOGLE_ULONGLONG(0); + acceptedid_ = GOOGLE_ULONGLONG(0); + acceptednodeid_ = GOOGLE_ULONGLONG(0); + acceptedvalue_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + checksum_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +AcceptorStateData::~AcceptorStateData() { + // @@protoc_insertion_point(destructor:phxpaxos.AcceptorStateData) + SharedDtor(); +} + +void AcceptorStateData::SharedDtor() { + acceptedvalue_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void AcceptorStateData::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* AcceptorStateData::descriptor() { + protobuf_AssignDescriptorsOnce(); + return AcceptorStateData_descriptor_; +} + +const AcceptorStateData& AcceptorStateData::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_paxos_5fmsg_2eproto(); + return *default_instance_; +} + +AcceptorStateData* AcceptorStateData::default_instance_ = NULL; + +AcceptorStateData* AcceptorStateData::New(::google::protobuf::Arena* arena) const { + AcceptorStateData* n = new AcceptorStateData; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void AcceptorStateData::Clear() { +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + if (_has_bits_[0 / 32] & 127u) { + ZR_(instanceid_, acceptednodeid_); + if (has_acceptedvalue()) { + acceptedvalue_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + checksum_ = 0u; + } + +#undef ZR_HELPER_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool AcceptorStateData::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxpaxos.AcceptorStateData) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 InstanceID = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &instanceid_))); + set_has_instanceid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_PromiseID; + break; + } + + // required uint64 PromiseID = 2; + case 2: { + if (tag == 16) { + parse_PromiseID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &promiseid_))); + set_has_promiseid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_PromiseNodeID; + break; + } + + // required uint64 PromiseNodeID = 3; + case 3: { + if (tag == 24) { + parse_PromiseNodeID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &promisenodeid_))); + set_has_promisenodeid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_AcceptedID; + break; + } + + // required uint64 AcceptedID = 4; + case 4: { + if (tag == 32) { + parse_AcceptedID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &acceptedid_))); + set_has_acceptedid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_AcceptedNodeID; + break; + } + + // required uint64 AcceptedNodeID = 5; + case 5: { + if (tag == 40) { + parse_AcceptedNodeID: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &acceptednodeid_))); + set_has_acceptednodeid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_AcceptedValue; + break; + } + + // required bytes AcceptedValue = 6; + case 6: { + if (tag == 50) { + parse_AcceptedValue: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_acceptedvalue())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(56)) goto parse_Checksum; + break; + } + + // required uint32 Checksum = 7; + case 7: { + if (tag == 56) { + parse_Checksum: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &checksum_))); + set_has_checksum(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxpaxos.AcceptorStateData) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxpaxos.AcceptorStateData) + return false; +#undef DO_ +} + +void AcceptorStateData::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxpaxos.AcceptorStateData) + // required uint64 InstanceID = 1; + if (has_instanceid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->instanceid(), output); + } + + // required uint64 PromiseID = 2; + if (has_promiseid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->promiseid(), output); + } + + // required uint64 PromiseNodeID = 3; + if (has_promisenodeid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->promisenodeid(), output); + } + + // required uint64 AcceptedID = 4; + if (has_acceptedid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->acceptedid(), output); + } + + // required uint64 AcceptedNodeID = 5; + if (has_acceptednodeid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(5, this->acceptednodeid(), output); + } + + // required bytes AcceptedValue = 6; + if (has_acceptedvalue()) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 6, this->acceptedvalue(), output); + } + + // required uint32 Checksum = 7; + if (has_checksum()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->checksum(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:phxpaxos.AcceptorStateData) +} + +::google::protobuf::uint8* AcceptorStateData::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxpaxos.AcceptorStateData) + // required uint64 InstanceID = 1; + if (has_instanceid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->instanceid(), target); + } + + // required uint64 PromiseID = 2; + if (has_promiseid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->promiseid(), target); + } + + // required uint64 PromiseNodeID = 3; + if (has_promisenodeid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->promisenodeid(), target); + } + + // required uint64 AcceptedID = 4; + if (has_acceptedid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->acceptedid(), target); + } + + // required uint64 AcceptedNodeID = 5; + if (has_acceptednodeid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(5, this->acceptednodeid(), target); + } + + // required bytes AcceptedValue = 6; + if (has_acceptedvalue()) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 6, this->acceptedvalue(), target); + } + + // required uint32 Checksum = 7; + if (has_checksum()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(7, this->checksum(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:phxpaxos.AcceptorStateData) + return target; +} + +int AcceptorStateData::RequiredFieldsByteSizeFallback() const { + int total_size = 0; + + if (has_instanceid()) { + // required uint64 InstanceID = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->instanceid()); + } + + if (has_promiseid()) { + // required uint64 PromiseID = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->promiseid()); + } + + if (has_promisenodeid()) { + // required uint64 PromiseNodeID = 3; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->promisenodeid()); + } + + if (has_acceptedid()) { + // required uint64 AcceptedID = 4; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->acceptedid()); + } + + if (has_acceptednodeid()) { + // required uint64 AcceptedNodeID = 5; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->acceptednodeid()); + } + + if (has_acceptedvalue()) { + // required bytes AcceptedValue = 6; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->acceptedvalue()); + } + + if (has_checksum()) { + // required uint32 Checksum = 7; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->checksum()); + } + + return total_size; +} +int AcceptorStateData::ByteSize() const { + int total_size = 0; + + if (((_has_bits_[0] & 0x0000007f) ^ 0x0000007f) == 0) { // All required fields are present. + // required uint64 InstanceID = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->instanceid()); + + // required uint64 PromiseID = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->promiseid()); + + // required uint64 PromiseNodeID = 3; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->promisenodeid()); + + // required uint64 AcceptedID = 4; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->acceptedid()); + + // required uint64 AcceptedNodeID = 5; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->acceptednodeid()); + + // required bytes AcceptedValue = 6; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->acceptedvalue()); + + // required uint32 Checksum = 7; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->checksum()); + + } else { + total_size += RequiredFieldsByteSizeFallback(); + } + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void AcceptorStateData::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const AcceptorStateData* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void AcceptorStateData::MergeFrom(const AcceptorStateData& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_instanceid()) { + set_instanceid(from.instanceid()); + } + if (from.has_promiseid()) { + set_promiseid(from.promiseid()); + } + if (from.has_promisenodeid()) { + set_promisenodeid(from.promisenodeid()); + } + if (from.has_acceptedid()) { + set_acceptedid(from.acceptedid()); + } + if (from.has_acceptednodeid()) { + set_acceptednodeid(from.acceptednodeid()); + } + if (from.has_acceptedvalue()) { + set_has_acceptedvalue(); + acceptedvalue_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.acceptedvalue_); + } + if (from.has_checksum()) { + set_checksum(from.checksum()); + } + } + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void AcceptorStateData::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void AcceptorStateData::CopyFrom(const AcceptorStateData& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool AcceptorStateData::IsInitialized() const { + if ((_has_bits_[0] & 0x0000007f) != 0x0000007f) return false; + + return true; +} + +void AcceptorStateData::Swap(AcceptorStateData* other) { + if (other == this) return; + InternalSwap(other); +} +void AcceptorStateData::InternalSwap(AcceptorStateData* other) { + std::swap(instanceid_, other->instanceid_); + std::swap(promiseid_, other->promiseid_); + std::swap(promisenodeid_, other->promisenodeid_); + std::swap(acceptedid_, other->acceptedid_); + std::swap(acceptednodeid_, other->acceptednodeid_); + acceptedvalue_.Swap(&other->acceptedvalue_); + std::swap(checksum_, other->checksum_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata AcceptorStateData::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = AcceptorStateData_descriptor_; + metadata.reflection = AcceptorStateData_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// AcceptorStateData + +// required uint64 InstanceID = 1; +bool AcceptorStateData::has_instanceid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void AcceptorStateData::set_has_instanceid() { + _has_bits_[0] |= 0x00000001u; +} +void AcceptorStateData::clear_has_instanceid() { + _has_bits_[0] &= ~0x00000001u; +} +void AcceptorStateData::clear_instanceid() { + instanceid_ = GOOGLE_ULONGLONG(0); + clear_has_instanceid(); +} + ::google::protobuf::uint64 AcceptorStateData::instanceid() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.InstanceID) + return instanceid_; +} + void AcceptorStateData::set_instanceid(::google::protobuf::uint64 value) { + set_has_instanceid(); + instanceid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.InstanceID) +} + +// required uint64 PromiseID = 2; +bool AcceptorStateData::has_promiseid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void AcceptorStateData::set_has_promiseid() { + _has_bits_[0] |= 0x00000002u; +} +void AcceptorStateData::clear_has_promiseid() { + _has_bits_[0] &= ~0x00000002u; +} +void AcceptorStateData::clear_promiseid() { + promiseid_ = GOOGLE_ULONGLONG(0); + clear_has_promiseid(); +} + ::google::protobuf::uint64 AcceptorStateData::promiseid() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.PromiseID) + return promiseid_; +} + void AcceptorStateData::set_promiseid(::google::protobuf::uint64 value) { + set_has_promiseid(); + promiseid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.PromiseID) +} + +// required uint64 PromiseNodeID = 3; +bool AcceptorStateData::has_promisenodeid() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +void AcceptorStateData::set_has_promisenodeid() { + _has_bits_[0] |= 0x00000004u; +} +void AcceptorStateData::clear_has_promisenodeid() { + _has_bits_[0] &= ~0x00000004u; +} +void AcceptorStateData::clear_promisenodeid() { + promisenodeid_ = GOOGLE_ULONGLONG(0); + clear_has_promisenodeid(); +} + ::google::protobuf::uint64 AcceptorStateData::promisenodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.PromiseNodeID) + return promisenodeid_; +} + void AcceptorStateData::set_promisenodeid(::google::protobuf::uint64 value) { + set_has_promisenodeid(); + promisenodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.PromiseNodeID) +} + +// required uint64 AcceptedID = 4; +bool AcceptorStateData::has_acceptedid() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +void AcceptorStateData::set_has_acceptedid() { + _has_bits_[0] |= 0x00000008u; +} +void AcceptorStateData::clear_has_acceptedid() { + _has_bits_[0] &= ~0x00000008u; +} +void AcceptorStateData::clear_acceptedid() { + acceptedid_ = GOOGLE_ULONGLONG(0); + clear_has_acceptedid(); +} + ::google::protobuf::uint64 AcceptorStateData::acceptedid() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.AcceptedID) + return acceptedid_; +} + void AcceptorStateData::set_acceptedid(::google::protobuf::uint64 value) { + set_has_acceptedid(); + acceptedid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.AcceptedID) +} + +// required uint64 AcceptedNodeID = 5; +bool AcceptorStateData::has_acceptednodeid() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +void AcceptorStateData::set_has_acceptednodeid() { + _has_bits_[0] |= 0x00000010u; +} +void AcceptorStateData::clear_has_acceptednodeid() { + _has_bits_[0] &= ~0x00000010u; +} +void AcceptorStateData::clear_acceptednodeid() { + acceptednodeid_ = GOOGLE_ULONGLONG(0); + clear_has_acceptednodeid(); +} + ::google::protobuf::uint64 AcceptorStateData::acceptednodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.AcceptedNodeID) + return acceptednodeid_; +} + void AcceptorStateData::set_acceptednodeid(::google::protobuf::uint64 value) { + set_has_acceptednodeid(); + acceptednodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.AcceptedNodeID) +} + +// required bytes AcceptedValue = 6; +bool AcceptorStateData::has_acceptedvalue() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +void AcceptorStateData::set_has_acceptedvalue() { + _has_bits_[0] |= 0x00000020u; +} +void AcceptorStateData::clear_has_acceptedvalue() { + _has_bits_[0] &= ~0x00000020u; +} +void AcceptorStateData::clear_acceptedvalue() { + acceptedvalue_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_acceptedvalue(); +} + const ::std::string& AcceptorStateData::acceptedvalue() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.AcceptedValue) + return acceptedvalue_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void AcceptorStateData::set_acceptedvalue(const ::std::string& value) { + set_has_acceptedvalue(); + acceptedvalue_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.AcceptedValue) +} + void AcceptorStateData::set_acceptedvalue(const char* value) { + set_has_acceptedvalue(); + acceptedvalue_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.AcceptorStateData.AcceptedValue) +} + void AcceptorStateData::set_acceptedvalue(const void* value, size_t size) { + set_has_acceptedvalue(); + acceptedvalue_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.AcceptorStateData.AcceptedValue) +} + ::std::string* AcceptorStateData::mutable_acceptedvalue() { + set_has_acceptedvalue(); + // @@protoc_insertion_point(field_mutable:phxpaxos.AcceptorStateData.AcceptedValue) + return acceptedvalue_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* AcceptorStateData::release_acceptedvalue() { + clear_has_acceptedvalue(); + return acceptedvalue_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void AcceptorStateData::set_allocated_acceptedvalue(::std::string* acceptedvalue) { + if (acceptedvalue != NULL) { + set_has_acceptedvalue(); + } else { + clear_has_acceptedvalue(); + } + acceptedvalue_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), acceptedvalue); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.AcceptorStateData.AcceptedValue) +} + +// required uint32 Checksum = 7; +bool AcceptorStateData::has_checksum() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +void AcceptorStateData::set_has_checksum() { + _has_bits_[0] |= 0x00000040u; +} +void AcceptorStateData::clear_has_checksum() { + _has_bits_[0] &= ~0x00000040u; +} +void AcceptorStateData::clear_checksum() { + checksum_ = 0u; + clear_has_checksum(); +} + ::google::protobuf::uint32 AcceptorStateData::checksum() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.Checksum) + return checksum_; +} + void AcceptorStateData::set_checksum(::google::protobuf::uint32 value) { + set_has_checksum(); + checksum_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.Checksum) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int PaxosNodeInfo::kRidFieldNumber; +const int PaxosNodeInfo::kNodeidFieldNumber; +#endif // !_MSC_VER + +PaxosNodeInfo::PaxosNodeInfo() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxpaxos.PaxosNodeInfo) +} + +void PaxosNodeInfo::InitAsDefaultInstance() { +} + +PaxosNodeInfo::PaxosNodeInfo(const PaxosNodeInfo& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxpaxos.PaxosNodeInfo) +} + +void PaxosNodeInfo::SharedCtor() { + _cached_size_ = 0; + rid_ = GOOGLE_ULONGLONG(0); + nodeid_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +PaxosNodeInfo::~PaxosNodeInfo() { + // @@protoc_insertion_point(destructor:phxpaxos.PaxosNodeInfo) + SharedDtor(); +} + +void PaxosNodeInfo::SharedDtor() { + if (this != default_instance_) { + } +} + +void PaxosNodeInfo::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* PaxosNodeInfo::descriptor() { + protobuf_AssignDescriptorsOnce(); + return PaxosNodeInfo_descriptor_; +} + +const PaxosNodeInfo& PaxosNodeInfo::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_paxos_5fmsg_2eproto(); + return *default_instance_; +} + +PaxosNodeInfo* PaxosNodeInfo::default_instance_ = NULL; + +PaxosNodeInfo* PaxosNodeInfo::New(::google::protobuf::Arena* arena) const { + PaxosNodeInfo* n = new PaxosNodeInfo; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void PaxosNodeInfo::Clear() { +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(rid_, nodeid_); + +#undef ZR_HELPER_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool PaxosNodeInfo::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxpaxos.PaxosNodeInfo) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 Rid = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &rid_))); + set_has_rid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_Nodeid; + break; + } + + // required uint64 Nodeid = 2; + case 2: { + if (tag == 16) { + parse_Nodeid: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &nodeid_))); + set_has_nodeid(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxpaxos.PaxosNodeInfo) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxpaxos.PaxosNodeInfo) + return false; +#undef DO_ +} + +void PaxosNodeInfo::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxpaxos.PaxosNodeInfo) + // required uint64 Rid = 1; + if (has_rid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->rid(), output); + } + + // required uint64 Nodeid = 2; + if (has_nodeid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->nodeid(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:phxpaxos.PaxosNodeInfo) +} + +::google::protobuf::uint8* PaxosNodeInfo::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxpaxos.PaxosNodeInfo) + // required uint64 Rid = 1; + if (has_rid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->rid(), target); + } + + // required uint64 Nodeid = 2; + if (has_nodeid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->nodeid(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:phxpaxos.PaxosNodeInfo) + return target; +} + +int PaxosNodeInfo::RequiredFieldsByteSizeFallback() const { + int total_size = 0; + + if (has_rid()) { + // required uint64 Rid = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->rid()); + } + + if (has_nodeid()) { + // required uint64 Nodeid = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->nodeid()); + } + + return total_size; +} +int PaxosNodeInfo::ByteSize() const { + int total_size = 0; + + if (((_has_bits_[0] & 0x00000003) ^ 0x00000003) == 0) { // All required fields are present. + // required uint64 Rid = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->rid()); + + // required uint64 Nodeid = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->nodeid()); + + } else { + total_size += RequiredFieldsByteSizeFallback(); + } + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void PaxosNodeInfo::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const PaxosNodeInfo* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void PaxosNodeInfo::MergeFrom(const PaxosNodeInfo& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_rid()) { + set_rid(from.rid()); + } + if (from.has_nodeid()) { + set_nodeid(from.nodeid()); + } + } + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void PaxosNodeInfo::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void PaxosNodeInfo::CopyFrom(const PaxosNodeInfo& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool PaxosNodeInfo::IsInitialized() const { + if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + + return true; +} + +void PaxosNodeInfo::Swap(PaxosNodeInfo* other) { + if (other == this) return; + InternalSwap(other); +} +void PaxosNodeInfo::InternalSwap(PaxosNodeInfo* other) { + std::swap(rid_, other->rid_); + std::swap(nodeid_, other->nodeid_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata PaxosNodeInfo::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = PaxosNodeInfo_descriptor_; + metadata.reflection = PaxosNodeInfo_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// PaxosNodeInfo + +// required uint64 Rid = 1; +bool PaxosNodeInfo::has_rid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void PaxosNodeInfo::set_has_rid() { + _has_bits_[0] |= 0x00000001u; +} +void PaxosNodeInfo::clear_has_rid() { + _has_bits_[0] &= ~0x00000001u; +} +void PaxosNodeInfo::clear_rid() { + rid_ = GOOGLE_ULONGLONG(0); + clear_has_rid(); +} + ::google::protobuf::uint64 PaxosNodeInfo::rid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosNodeInfo.Rid) + return rid_; +} + void PaxosNodeInfo::set_rid(::google::protobuf::uint64 value) { + set_has_rid(); + rid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosNodeInfo.Rid) +} + +// required uint64 Nodeid = 2; +bool PaxosNodeInfo::has_nodeid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void PaxosNodeInfo::set_has_nodeid() { + _has_bits_[0] |= 0x00000002u; +} +void PaxosNodeInfo::clear_has_nodeid() { + _has_bits_[0] &= ~0x00000002u; +} +void PaxosNodeInfo::clear_nodeid() { + nodeid_ = GOOGLE_ULONGLONG(0); + clear_has_nodeid(); +} + ::google::protobuf::uint64 PaxosNodeInfo::nodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosNodeInfo.Nodeid) + return nodeid_; +} + void PaxosNodeInfo::set_nodeid(::google::protobuf::uint64 value) { + set_has_nodeid(); + nodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosNodeInfo.Nodeid) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int SystemVariables::kGidFieldNumber; +const int SystemVariables::kMemberShipFieldNumber; +const int SystemVariables::kVersionFieldNumber; +#endif // !_MSC_VER + +SystemVariables::SystemVariables() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxpaxos.SystemVariables) +} + +void SystemVariables::InitAsDefaultInstance() { +} + +SystemVariables::SystemVariables(const SystemVariables& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxpaxos.SystemVariables) +} + +void SystemVariables::SharedCtor() { + _cached_size_ = 0; + gid_ = GOOGLE_ULONGLONG(0); + version_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +SystemVariables::~SystemVariables() { + // @@protoc_insertion_point(destructor:phxpaxos.SystemVariables) + SharedDtor(); +} + +void SystemVariables::SharedDtor() { + if (this != default_instance_) { + } +} + +void SystemVariables::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* SystemVariables::descriptor() { + protobuf_AssignDescriptorsOnce(); + return SystemVariables_descriptor_; +} + +const SystemVariables& SystemVariables::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_paxos_5fmsg_2eproto(); + return *default_instance_; +} + +SystemVariables* SystemVariables::default_instance_ = NULL; + +SystemVariables* SystemVariables::New(::google::protobuf::Arena* arena) const { + SystemVariables* n = new SystemVariables; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void SystemVariables::Clear() { + if (_has_bits_[0 / 32] & 5u) { + gid_ = GOOGLE_ULONGLONG(0); + version_ = GOOGLE_ULONGLONG(0); + } + membership_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool SystemVariables::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxpaxos.SystemVariables) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 Gid = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &gid_))); + set_has_gid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_MemberShip; + break; + } + + // repeated .phxpaxos.PaxosNodeInfo MemberShip = 2; + case 2: { + if (tag == 18) { + parse_MemberShip: + DO_(input->IncrementRecursionDepth()); + parse_loop_MemberShip: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_membership())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_loop_MemberShip; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectTag(24)) goto parse_Version; + break; + } + + // required uint64 Version = 3; + case 3: { + if (tag == 24) { + parse_Version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &version_))); + set_has_version(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxpaxos.SystemVariables) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxpaxos.SystemVariables) + return false; +#undef DO_ +} + +void SystemVariables::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxpaxos.SystemVariables) + // required uint64 Gid = 1; + if (has_gid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->gid(), output); + } + + // repeated .phxpaxos.PaxosNodeInfo MemberShip = 2; + for (unsigned int i = 0, n = this->membership_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->membership(i), output); + } + + // required uint64 Version = 3; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->version(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:phxpaxos.SystemVariables) +} + +::google::protobuf::uint8* SystemVariables::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxpaxos.SystemVariables) + // required uint64 Gid = 1; + if (has_gid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->gid(), target); + } + + // repeated .phxpaxos.PaxosNodeInfo MemberShip = 2; + for (unsigned int i = 0, n = this->membership_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->membership(i), target); + } + + // required uint64 Version = 3; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->version(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:phxpaxos.SystemVariables) + return target; +} + +int SystemVariables::RequiredFieldsByteSizeFallback() const { + int total_size = 0; + + if (has_gid()) { + // required uint64 Gid = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->gid()); + } + + if (has_version()) { + // required uint64 Version = 3; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->version()); + } + + return total_size; +} +int SystemVariables::ByteSize() const { + int total_size = 0; + + if (((_has_bits_[0] & 0x00000005) ^ 0x00000005) == 0) { // All required fields are present. + // required uint64 Gid = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->gid()); + + // required uint64 Version = 3; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->version()); + + } else { + total_size += RequiredFieldsByteSizeFallback(); + } + // repeated .phxpaxos.PaxosNodeInfo MemberShip = 2; + total_size += 1 * this->membership_size(); + for (int i = 0; i < this->membership_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->membership(i)); + } + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void SystemVariables::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const SystemVariables* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void SystemVariables::MergeFrom(const SystemVariables& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + membership_.MergeFrom(from.membership_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_gid()) { + set_gid(from.gid()); + } + if (from.has_version()) { + set_version(from.version()); + } + } + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void SystemVariables::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void SystemVariables::CopyFrom(const SystemVariables& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SystemVariables::IsInitialized() const { + if ((_has_bits_[0] & 0x00000005) != 0x00000005) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->membership())) return false; + return true; +} + +void SystemVariables::Swap(SystemVariables* other) { + if (other == this) return; + InternalSwap(other); +} +void SystemVariables::InternalSwap(SystemVariables* other) { + std::swap(gid_, other->gid_); + membership_.UnsafeArenaSwap(&other->membership_); + std::swap(version_, other->version_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata SystemVariables::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = SystemVariables_descriptor_; + metadata.reflection = SystemVariables_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// SystemVariables + +// required uint64 Gid = 1; +bool SystemVariables::has_gid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void SystemVariables::set_has_gid() { + _has_bits_[0] |= 0x00000001u; +} +void SystemVariables::clear_has_gid() { + _has_bits_[0] &= ~0x00000001u; +} +void SystemVariables::clear_gid() { + gid_ = GOOGLE_ULONGLONG(0); + clear_has_gid(); +} + ::google::protobuf::uint64 SystemVariables::gid() const { + // @@protoc_insertion_point(field_get:phxpaxos.SystemVariables.Gid) + return gid_; +} + void SystemVariables::set_gid(::google::protobuf::uint64 value) { + set_has_gid(); + gid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.SystemVariables.Gid) +} + +// repeated .phxpaxos.PaxosNodeInfo MemberShip = 2; +int SystemVariables::membership_size() const { + return membership_.size(); +} +void SystemVariables::clear_membership() { + membership_.Clear(); +} +const ::phxpaxos::PaxosNodeInfo& SystemVariables::membership(int index) const { + // @@protoc_insertion_point(field_get:phxpaxos.SystemVariables.MemberShip) + return membership_.Get(index); +} +::phxpaxos::PaxosNodeInfo* SystemVariables::mutable_membership(int index) { + // @@protoc_insertion_point(field_mutable:phxpaxos.SystemVariables.MemberShip) + return membership_.Mutable(index); +} +::phxpaxos::PaxosNodeInfo* SystemVariables::add_membership() { + // @@protoc_insertion_point(field_add:phxpaxos.SystemVariables.MemberShip) + return membership_.Add(); +} +::google::protobuf::RepeatedPtrField< ::phxpaxos::PaxosNodeInfo >* +SystemVariables::mutable_membership() { + // @@protoc_insertion_point(field_mutable_list:phxpaxos.SystemVariables.MemberShip) + return &membership_; +} +const ::google::protobuf::RepeatedPtrField< ::phxpaxos::PaxosNodeInfo >& +SystemVariables::membership() const { + // @@protoc_insertion_point(field_list:phxpaxos.SystemVariables.MemberShip) + return membership_; +} + +// required uint64 Version = 3; +bool SystemVariables::has_version() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +void SystemVariables::set_has_version() { + _has_bits_[0] |= 0x00000004u; +} +void SystemVariables::clear_has_version() { + _has_bits_[0] &= ~0x00000004u; +} +void SystemVariables::clear_version() { + version_ = GOOGLE_ULONGLONG(0); + clear_has_version(); +} + ::google::protobuf::uint64 SystemVariables::version() const { + // @@protoc_insertion_point(field_get:phxpaxos.SystemVariables.Version) + return version_; +} + void SystemVariables::set_version(::google::protobuf::uint64 value) { + set_has_version(); + version_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.SystemVariables.Version) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int MasterVariables::kMasterNodeidFieldNumber; +const int MasterVariables::kVersionFieldNumber; +const int MasterVariables::kLeaseTimeFieldNumber; +#endif // !_MSC_VER + +MasterVariables::MasterVariables() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxpaxos.MasterVariables) +} + +void MasterVariables::InitAsDefaultInstance() { +} + +MasterVariables::MasterVariables(const MasterVariables& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxpaxos.MasterVariables) +} + +void MasterVariables::SharedCtor() { + _cached_size_ = 0; + masternodeid_ = GOOGLE_ULONGLONG(0); + version_ = GOOGLE_ULONGLONG(0); + leasetime_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +MasterVariables::~MasterVariables() { + // @@protoc_insertion_point(destructor:phxpaxos.MasterVariables) + SharedDtor(); +} + +void MasterVariables::SharedDtor() { + if (this != default_instance_) { + } +} + +void MasterVariables::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* MasterVariables::descriptor() { + protobuf_AssignDescriptorsOnce(); + return MasterVariables_descriptor_; +} + +const MasterVariables& MasterVariables::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_paxos_5fmsg_2eproto(); + return *default_instance_; +} + +MasterVariables* MasterVariables::default_instance_ = NULL; + +MasterVariables* MasterVariables::New(::google::protobuf::Arena* arena) const { + MasterVariables* n = new MasterVariables; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void MasterVariables::Clear() { +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(masternodeid_, leasetime_); + +#undef ZR_HELPER_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool MasterVariables::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxpaxos.MasterVariables) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 MasterNodeid = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &masternodeid_))); + set_has_masternodeid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_Version; + break; + } + + // required uint64 Version = 2; + case 2: { + if (tag == 16) { + parse_Version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &version_))); + set_has_version(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_LeaseTime; + break; + } + + // required uint32 LeaseTime = 3; + case 3: { + if (tag == 24) { + parse_LeaseTime: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &leasetime_))); + set_has_leasetime(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxpaxos.MasterVariables) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxpaxos.MasterVariables) + return false; +#undef DO_ +} + +void MasterVariables::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxpaxos.MasterVariables) + // required uint64 MasterNodeid = 1; + if (has_masternodeid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->masternodeid(), output); + } + + // required uint64 Version = 2; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->version(), output); + } + + // required uint32 LeaseTime = 3; + if (has_leasetime()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->leasetime(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:phxpaxos.MasterVariables) +} + +::google::protobuf::uint8* MasterVariables::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxpaxos.MasterVariables) + // required uint64 MasterNodeid = 1; + if (has_masternodeid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->masternodeid(), target); + } + + // required uint64 Version = 2; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->version(), target); + } + + // required uint32 LeaseTime = 3; + if (has_leasetime()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->leasetime(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:phxpaxos.MasterVariables) + return target; +} + +int MasterVariables::RequiredFieldsByteSizeFallback() const { + int total_size = 0; + + if (has_masternodeid()) { + // required uint64 MasterNodeid = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->masternodeid()); + } + + if (has_version()) { + // required uint64 Version = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->version()); + } + + if (has_leasetime()) { + // required uint32 LeaseTime = 3; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->leasetime()); + } + + return total_size; +} +int MasterVariables::ByteSize() const { + int total_size = 0; + + if (((_has_bits_[0] & 0x00000007) ^ 0x00000007) == 0) { // All required fields are present. + // required uint64 MasterNodeid = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->masternodeid()); + + // required uint64 Version = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->version()); + + // required uint32 LeaseTime = 3; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->leasetime()); + + } else { + total_size += RequiredFieldsByteSizeFallback(); + } + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void MasterVariables::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const MasterVariables* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void MasterVariables::MergeFrom(const MasterVariables& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_masternodeid()) { + set_masternodeid(from.masternodeid()); + } + if (from.has_version()) { + set_version(from.version()); + } + if (from.has_leasetime()) { + set_leasetime(from.leasetime()); + } + } + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void MasterVariables::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void MasterVariables::CopyFrom(const MasterVariables& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MasterVariables::IsInitialized() const { + if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; + + return true; +} + +void MasterVariables::Swap(MasterVariables* other) { + if (other == this) return; + InternalSwap(other); +} +void MasterVariables::InternalSwap(MasterVariables* other) { + std::swap(masternodeid_, other->masternodeid_); + std::swap(version_, other->version_); + std::swap(leasetime_, other->leasetime_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata MasterVariables::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = MasterVariables_descriptor_; + metadata.reflection = MasterVariables_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// MasterVariables + +// required uint64 MasterNodeid = 1; +bool MasterVariables::has_masternodeid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void MasterVariables::set_has_masternodeid() { + _has_bits_[0] |= 0x00000001u; +} +void MasterVariables::clear_has_masternodeid() { + _has_bits_[0] &= ~0x00000001u; +} +void MasterVariables::clear_masternodeid() { + masternodeid_ = GOOGLE_ULONGLONG(0); + clear_has_masternodeid(); +} + ::google::protobuf::uint64 MasterVariables::masternodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterVariables.MasterNodeid) + return masternodeid_; +} + void MasterVariables::set_masternodeid(::google::protobuf::uint64 value) { + set_has_masternodeid(); + masternodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterVariables.MasterNodeid) +} + +// required uint64 Version = 2; +bool MasterVariables::has_version() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void MasterVariables::set_has_version() { + _has_bits_[0] |= 0x00000002u; +} +void MasterVariables::clear_has_version() { + _has_bits_[0] &= ~0x00000002u; +} +void MasterVariables::clear_version() { + version_ = GOOGLE_ULONGLONG(0); + clear_has_version(); +} + ::google::protobuf::uint64 MasterVariables::version() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterVariables.Version) + return version_; +} + void MasterVariables::set_version(::google::protobuf::uint64 value) { + set_has_version(); + version_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterVariables.Version) +} + +// required uint32 LeaseTime = 3; +bool MasterVariables::has_leasetime() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +void MasterVariables::set_has_leasetime() { + _has_bits_[0] |= 0x00000004u; +} +void MasterVariables::clear_has_leasetime() { + _has_bits_[0] &= ~0x00000004u; +} +void MasterVariables::clear_leasetime() { + leasetime_ = 0u; + clear_has_leasetime(); +} + ::google::protobuf::uint32 MasterVariables::leasetime() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterVariables.LeaseTime) + return leasetime_; +} + void MasterVariables::set_leasetime(::google::protobuf::uint32 value) { + set_has_leasetime(); + leasetime_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterVariables.LeaseTime) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace phxpaxos + +// @@protoc_insertion_point(global_scope) diff --git a/src/comm/paxos_msg.pb.h b/src/comm/paxos_msg.pb.h new file mode 100644 index 000000000..605fa7534 --- /dev/null +++ b/src/comm/paxos_msg.pb.h @@ -0,0 +1,2413 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: paxos_msg.proto + +#ifndef PROTOBUF_paxos_5fmsg_2eproto__INCLUDED +#define PROTOBUF_paxos_5fmsg_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace phxpaxos { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_paxos_5fmsg_2eproto(); +void protobuf_AssignDesc_paxos_5fmsg_2eproto(); +void protobuf_ShutdownFile_paxos_5fmsg_2eproto(); + +class AcceptorStateData; +class CheckpointMsg; +class Header; +class MasterVariables; +class PaxosMsg; +class PaxosNodeInfo; +class SystemVariables; + +// =================================================================== + +class Header : public ::google::protobuf::Message { + public: + Header(); + virtual ~Header(); + + Header(const Header& from); + + inline Header& operator=(const Header& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Header& default_instance(); + + void Swap(Header* other); + + // implements Message ---------------------------------------------- + + inline Header* New() const { return New(NULL); } + + Header* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Header& from); + void MergeFrom(const Header& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Header* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 gid = 1; + bool has_gid() const; + void clear_gid(); + static const int kGidFieldNumber = 1; + ::google::protobuf::uint64 gid() const; + void set_gid(::google::protobuf::uint64 value); + + // required uint64 rid = 2; + bool has_rid() const; + void clear_rid(); + static const int kRidFieldNumber = 2; + ::google::protobuf::uint64 rid() const; + void set_rid(::google::protobuf::uint64 value); + + // required int32 cmdid = 3; + bool has_cmdid() const; + void clear_cmdid(); + static const int kCmdidFieldNumber = 3; + ::google::protobuf::int32 cmdid() const; + void set_cmdid(::google::protobuf::int32 value); + + // optional int32 version = 4; + bool has_version() const; + void clear_version(); + static const int kVersionFieldNumber = 4; + ::google::protobuf::int32 version() const; + void set_version(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:phxpaxos.Header) + private: + inline void set_has_gid(); + inline void clear_has_gid(); + inline void set_has_rid(); + inline void clear_has_rid(); + inline void set_has_cmdid(); + inline void clear_has_cmdid(); + inline void set_has_version(); + inline void clear_has_version(); + + // helper for ByteSize() + int RequiredFieldsByteSizeFallback() const; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 gid_; + ::google::protobuf::uint64 rid_; + ::google::protobuf::int32 cmdid_; + ::google::protobuf::int32 version_; + friend void protobuf_AddDesc_paxos_5fmsg_2eproto(); + friend void protobuf_AssignDesc_paxos_5fmsg_2eproto(); + friend void protobuf_ShutdownFile_paxos_5fmsg_2eproto(); + + void InitAsDefaultInstance(); + static Header* default_instance_; +}; +// ------------------------------------------------------------------- + +class PaxosMsg : public ::google::protobuf::Message { + public: + PaxosMsg(); + virtual ~PaxosMsg(); + + PaxosMsg(const PaxosMsg& from); + + inline PaxosMsg& operator=(const PaxosMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const PaxosMsg& default_instance(); + + void Swap(PaxosMsg* other); + + // implements Message ---------------------------------------------- + + inline PaxosMsg* New() const { return New(NULL); } + + PaxosMsg* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const PaxosMsg& from); + void MergeFrom(const PaxosMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(PaxosMsg* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 MsgType = 1; + bool has_msgtype() const; + void clear_msgtype(); + static const int kMsgTypeFieldNumber = 1; + ::google::protobuf::int32 msgtype() const; + void set_msgtype(::google::protobuf::int32 value); + + // optional uint64 InstanceID = 2; + bool has_instanceid() const; + void clear_instanceid(); + static const int kInstanceIDFieldNumber = 2; + ::google::protobuf::uint64 instanceid() const; + void set_instanceid(::google::protobuf::uint64 value); + + // optional uint64 NodeID = 3; + bool has_nodeid() const; + void clear_nodeid(); + static const int kNodeIDFieldNumber = 3; + ::google::protobuf::uint64 nodeid() const; + void set_nodeid(::google::protobuf::uint64 value); + + // optional uint64 ProposalID = 4; + bool has_proposalid() const; + void clear_proposalid(); + static const int kProposalIDFieldNumber = 4; + ::google::protobuf::uint64 proposalid() const; + void set_proposalid(::google::protobuf::uint64 value); + + // optional uint64 ProposalNodeID = 5; + bool has_proposalnodeid() const; + void clear_proposalnodeid(); + static const int kProposalNodeIDFieldNumber = 5; + ::google::protobuf::uint64 proposalnodeid() const; + void set_proposalnodeid(::google::protobuf::uint64 value); + + // optional bytes Value = 6; + bool has_value() const; + void clear_value(); + static const int kValueFieldNumber = 6; + const ::std::string& value() const; + void set_value(const ::std::string& value); + void set_value(const char* value); + void set_value(const void* value, size_t size); + ::std::string* mutable_value(); + ::std::string* release_value(); + void set_allocated_value(::std::string* value); + + // optional uint64 PreAcceptID = 7; + bool has_preacceptid() const; + void clear_preacceptid(); + static const int kPreAcceptIDFieldNumber = 7; + ::google::protobuf::uint64 preacceptid() const; + void set_preacceptid(::google::protobuf::uint64 value); + + // optional uint64 PreAcceptNodeID = 8; + bool has_preacceptnodeid() const; + void clear_preacceptnodeid(); + static const int kPreAcceptNodeIDFieldNumber = 8; + ::google::protobuf::uint64 preacceptnodeid() const; + void set_preacceptnodeid(::google::protobuf::uint64 value); + + // optional uint64 RejectByPromiseID = 9; + bool has_rejectbypromiseid() const; + void clear_rejectbypromiseid(); + static const int kRejectByPromiseIDFieldNumber = 9; + ::google::protobuf::uint64 rejectbypromiseid() const; + void set_rejectbypromiseid(::google::protobuf::uint64 value); + + // optional uint64 NowInstanceID = 10; + bool has_nowinstanceid() const; + void clear_nowinstanceid(); + static const int kNowInstanceIDFieldNumber = 10; + ::google::protobuf::uint64 nowinstanceid() const; + void set_nowinstanceid(::google::protobuf::uint64 value); + + // optional uint64 MinChosenInstanceID = 11; + bool has_minchoseninstanceid() const; + void clear_minchoseninstanceid(); + static const int kMinChosenInstanceIDFieldNumber = 11; + ::google::protobuf::uint64 minchoseninstanceid() const; + void set_minchoseninstanceid(::google::protobuf::uint64 value); + + // optional uint32 LastChecksum = 12; + bool has_lastchecksum() const; + void clear_lastchecksum(); + static const int kLastChecksumFieldNumber = 12; + ::google::protobuf::uint32 lastchecksum() const; + void set_lastchecksum(::google::protobuf::uint32 value); + + // optional uint32 Flag = 13; + bool has_flag() const; + void clear_flag(); + static const int kFlagFieldNumber = 13; + ::google::protobuf::uint32 flag() const; + void set_flag(::google::protobuf::uint32 value); + + // optional bytes SystemVariables = 14; + bool has_systemvariables() const; + void clear_systemvariables(); + static const int kSystemVariablesFieldNumber = 14; + const ::std::string& systemvariables() const; + void set_systemvariables(const ::std::string& value); + void set_systemvariables(const char* value); + void set_systemvariables(const void* value, size_t size); + ::std::string* mutable_systemvariables(); + ::std::string* release_systemvariables(); + void set_allocated_systemvariables(::std::string* systemvariables); + + // optional bytes MasterVariables = 15; + bool has_mastervariables() const; + void clear_mastervariables(); + static const int kMasterVariablesFieldNumber = 15; + const ::std::string& mastervariables() const; + void set_mastervariables(const ::std::string& value); + void set_mastervariables(const char* value); + void set_mastervariables(const void* value, size_t size); + ::std::string* mutable_mastervariables(); + ::std::string* release_mastervariables(); + void set_allocated_mastervariables(::std::string* mastervariables); + + // @@protoc_insertion_point(class_scope:phxpaxos.PaxosMsg) + private: + inline void set_has_msgtype(); + inline void clear_has_msgtype(); + inline void set_has_instanceid(); + inline void clear_has_instanceid(); + inline void set_has_nodeid(); + inline void clear_has_nodeid(); + inline void set_has_proposalid(); + inline void clear_has_proposalid(); + inline void set_has_proposalnodeid(); + inline void clear_has_proposalnodeid(); + inline void set_has_value(); + inline void clear_has_value(); + inline void set_has_preacceptid(); + inline void clear_has_preacceptid(); + inline void set_has_preacceptnodeid(); + inline void clear_has_preacceptnodeid(); + inline void set_has_rejectbypromiseid(); + inline void clear_has_rejectbypromiseid(); + inline void set_has_nowinstanceid(); + inline void clear_has_nowinstanceid(); + inline void set_has_minchoseninstanceid(); + inline void clear_has_minchoseninstanceid(); + inline void set_has_lastchecksum(); + inline void clear_has_lastchecksum(); + inline void set_has_flag(); + inline void clear_has_flag(); + inline void set_has_systemvariables(); + inline void clear_has_systemvariables(); + inline void set_has_mastervariables(); + inline void clear_has_mastervariables(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 instanceid_; + ::google::protobuf::uint64 nodeid_; + ::google::protobuf::uint64 proposalid_; + ::google::protobuf::uint64 proposalnodeid_; + ::google::protobuf::internal::ArenaStringPtr value_; + ::google::protobuf::int32 msgtype_; + ::google::protobuf::uint32 lastchecksum_; + ::google::protobuf::uint64 preacceptid_; + ::google::protobuf::uint64 preacceptnodeid_; + ::google::protobuf::uint64 rejectbypromiseid_; + ::google::protobuf::uint64 nowinstanceid_; + ::google::protobuf::uint64 minchoseninstanceid_; + ::google::protobuf::internal::ArenaStringPtr systemvariables_; + ::google::protobuf::internal::ArenaStringPtr mastervariables_; + ::google::protobuf::uint32 flag_; + friend void protobuf_AddDesc_paxos_5fmsg_2eproto(); + friend void protobuf_AssignDesc_paxos_5fmsg_2eproto(); + friend void protobuf_ShutdownFile_paxos_5fmsg_2eproto(); + + void InitAsDefaultInstance(); + static PaxosMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class CheckpointMsg : public ::google::protobuf::Message { + public: + CheckpointMsg(); + virtual ~CheckpointMsg(); + + CheckpointMsg(const CheckpointMsg& from); + + inline CheckpointMsg& operator=(const CheckpointMsg& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const CheckpointMsg& default_instance(); + + void Swap(CheckpointMsg* other); + + // implements Message ---------------------------------------------- + + inline CheckpointMsg* New() const { return New(NULL); } + + CheckpointMsg* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const CheckpointMsg& from); + void MergeFrom(const CheckpointMsg& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(CheckpointMsg* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required int32 MsgType = 1; + bool has_msgtype() const; + void clear_msgtype(); + static const int kMsgTypeFieldNumber = 1; + ::google::protobuf::int32 msgtype() const; + void set_msgtype(::google::protobuf::int32 value); + + // required uint64 NodeID = 2; + bool has_nodeid() const; + void clear_nodeid(); + static const int kNodeIDFieldNumber = 2; + ::google::protobuf::uint64 nodeid() const; + void set_nodeid(::google::protobuf::uint64 value); + + // optional int32 Flag = 3; + bool has_flag() const; + void clear_flag(); + static const int kFlagFieldNumber = 3; + ::google::protobuf::int32 flag() const; + void set_flag(::google::protobuf::int32 value); + + // required uint64 UUID = 4; + bool has_uuid() const; + void clear_uuid(); + static const int kUUIDFieldNumber = 4; + ::google::protobuf::uint64 uuid() const; + void set_uuid(::google::protobuf::uint64 value); + + // required uint64 Sequence = 5; + bool has_sequence() const; + void clear_sequence(); + static const int kSequenceFieldNumber = 5; + ::google::protobuf::uint64 sequence() const; + void set_sequence(::google::protobuf::uint64 value); + + // optional uint64 CheckpointInstanceID = 6; + bool has_checkpointinstanceid() const; + void clear_checkpointinstanceid(); + static const int kCheckpointInstanceIDFieldNumber = 6; + ::google::protobuf::uint64 checkpointinstanceid() const; + void set_checkpointinstanceid(::google::protobuf::uint64 value); + + // optional uint32 Checksum = 7; + bool has_checksum() const; + void clear_checksum(); + static const int kChecksumFieldNumber = 7; + ::google::protobuf::uint32 checksum() const; + void set_checksum(::google::protobuf::uint32 value); + + // optional string FilePath = 8; + bool has_filepath() const; + void clear_filepath(); + static const int kFilePathFieldNumber = 8; + const ::std::string& filepath() const; + void set_filepath(const ::std::string& value); + void set_filepath(const char* value); + void set_filepath(const char* value, size_t size); + ::std::string* mutable_filepath(); + ::std::string* release_filepath(); + void set_allocated_filepath(::std::string* filepath); + + // optional int32 SMID = 9; + bool has_smid() const; + void clear_smid(); + static const int kSMIDFieldNumber = 9; + ::google::protobuf::int32 smid() const; + void set_smid(::google::protobuf::int32 value); + + // optional uint64 Offset = 10; + bool has_offset() const; + void clear_offset(); + static const int kOffsetFieldNumber = 10; + ::google::protobuf::uint64 offset() const; + void set_offset(::google::protobuf::uint64 value); + + // optional bytes Buffer = 11; + bool has_buffer() const; + void clear_buffer(); + static const int kBufferFieldNumber = 11; + const ::std::string& buffer() const; + void set_buffer(const ::std::string& value); + void set_buffer(const char* value); + void set_buffer(const void* value, size_t size); + ::std::string* mutable_buffer(); + ::std::string* release_buffer(); + void set_allocated_buffer(::std::string* buffer); + + // @@protoc_insertion_point(class_scope:phxpaxos.CheckpointMsg) + private: + inline void set_has_msgtype(); + inline void clear_has_msgtype(); + inline void set_has_nodeid(); + inline void clear_has_nodeid(); + inline void set_has_flag(); + inline void clear_has_flag(); + inline void set_has_uuid(); + inline void clear_has_uuid(); + inline void set_has_sequence(); + inline void clear_has_sequence(); + inline void set_has_checkpointinstanceid(); + inline void clear_has_checkpointinstanceid(); + inline void set_has_checksum(); + inline void clear_has_checksum(); + inline void set_has_filepath(); + inline void clear_has_filepath(); + inline void set_has_smid(); + inline void clear_has_smid(); + inline void set_has_offset(); + inline void clear_has_offset(); + inline void set_has_buffer(); + inline void clear_has_buffer(); + + // helper for ByteSize() + int RequiredFieldsByteSizeFallback() const; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 nodeid_; + ::google::protobuf::int32 msgtype_; + ::google::protobuf::int32 flag_; + ::google::protobuf::uint64 uuid_; + ::google::protobuf::uint64 sequence_; + ::google::protobuf::uint64 checkpointinstanceid_; + ::google::protobuf::internal::ArenaStringPtr filepath_; + ::google::protobuf::uint32 checksum_; + ::google::protobuf::int32 smid_; + ::google::protobuf::uint64 offset_; + ::google::protobuf::internal::ArenaStringPtr buffer_; + friend void protobuf_AddDesc_paxos_5fmsg_2eproto(); + friend void protobuf_AssignDesc_paxos_5fmsg_2eproto(); + friend void protobuf_ShutdownFile_paxos_5fmsg_2eproto(); + + void InitAsDefaultInstance(); + static CheckpointMsg* default_instance_; +}; +// ------------------------------------------------------------------- + +class AcceptorStateData : public ::google::protobuf::Message { + public: + AcceptorStateData(); + virtual ~AcceptorStateData(); + + AcceptorStateData(const AcceptorStateData& from); + + inline AcceptorStateData& operator=(const AcceptorStateData& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const AcceptorStateData& default_instance(); + + void Swap(AcceptorStateData* other); + + // implements Message ---------------------------------------------- + + inline AcceptorStateData* New() const { return New(NULL); } + + AcceptorStateData* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const AcceptorStateData& from); + void MergeFrom(const AcceptorStateData& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(AcceptorStateData* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 InstanceID = 1; + bool has_instanceid() const; + void clear_instanceid(); + static const int kInstanceIDFieldNumber = 1; + ::google::protobuf::uint64 instanceid() const; + void set_instanceid(::google::protobuf::uint64 value); + + // required uint64 PromiseID = 2; + bool has_promiseid() const; + void clear_promiseid(); + static const int kPromiseIDFieldNumber = 2; + ::google::protobuf::uint64 promiseid() const; + void set_promiseid(::google::protobuf::uint64 value); + + // required uint64 PromiseNodeID = 3; + bool has_promisenodeid() const; + void clear_promisenodeid(); + static const int kPromiseNodeIDFieldNumber = 3; + ::google::protobuf::uint64 promisenodeid() const; + void set_promisenodeid(::google::protobuf::uint64 value); + + // required uint64 AcceptedID = 4; + bool has_acceptedid() const; + void clear_acceptedid(); + static const int kAcceptedIDFieldNumber = 4; + ::google::protobuf::uint64 acceptedid() const; + void set_acceptedid(::google::protobuf::uint64 value); + + // required uint64 AcceptedNodeID = 5; + bool has_acceptednodeid() const; + void clear_acceptednodeid(); + static const int kAcceptedNodeIDFieldNumber = 5; + ::google::protobuf::uint64 acceptednodeid() const; + void set_acceptednodeid(::google::protobuf::uint64 value); + + // required bytes AcceptedValue = 6; + bool has_acceptedvalue() const; + void clear_acceptedvalue(); + static const int kAcceptedValueFieldNumber = 6; + const ::std::string& acceptedvalue() const; + void set_acceptedvalue(const ::std::string& value); + void set_acceptedvalue(const char* value); + void set_acceptedvalue(const void* value, size_t size); + ::std::string* mutable_acceptedvalue(); + ::std::string* release_acceptedvalue(); + void set_allocated_acceptedvalue(::std::string* acceptedvalue); + + // required uint32 Checksum = 7; + bool has_checksum() const; + void clear_checksum(); + static const int kChecksumFieldNumber = 7; + ::google::protobuf::uint32 checksum() const; + void set_checksum(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:phxpaxos.AcceptorStateData) + private: + inline void set_has_instanceid(); + inline void clear_has_instanceid(); + inline void set_has_promiseid(); + inline void clear_has_promiseid(); + inline void set_has_promisenodeid(); + inline void clear_has_promisenodeid(); + inline void set_has_acceptedid(); + inline void clear_has_acceptedid(); + inline void set_has_acceptednodeid(); + inline void clear_has_acceptednodeid(); + inline void set_has_acceptedvalue(); + inline void clear_has_acceptedvalue(); + inline void set_has_checksum(); + inline void clear_has_checksum(); + + // helper for ByteSize() + int RequiredFieldsByteSizeFallback() const; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 instanceid_; + ::google::protobuf::uint64 promiseid_; + ::google::protobuf::uint64 promisenodeid_; + ::google::protobuf::uint64 acceptedid_; + ::google::protobuf::uint64 acceptednodeid_; + ::google::protobuf::internal::ArenaStringPtr acceptedvalue_; + ::google::protobuf::uint32 checksum_; + friend void protobuf_AddDesc_paxos_5fmsg_2eproto(); + friend void protobuf_AssignDesc_paxos_5fmsg_2eproto(); + friend void protobuf_ShutdownFile_paxos_5fmsg_2eproto(); + + void InitAsDefaultInstance(); + static AcceptorStateData* default_instance_; +}; +// ------------------------------------------------------------------- + +class PaxosNodeInfo : public ::google::protobuf::Message { + public: + PaxosNodeInfo(); + virtual ~PaxosNodeInfo(); + + PaxosNodeInfo(const PaxosNodeInfo& from); + + inline PaxosNodeInfo& operator=(const PaxosNodeInfo& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const PaxosNodeInfo& default_instance(); + + void Swap(PaxosNodeInfo* other); + + // implements Message ---------------------------------------------- + + inline PaxosNodeInfo* New() const { return New(NULL); } + + PaxosNodeInfo* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const PaxosNodeInfo& from); + void MergeFrom(const PaxosNodeInfo& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(PaxosNodeInfo* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 Rid = 1; + bool has_rid() const; + void clear_rid(); + static const int kRidFieldNumber = 1; + ::google::protobuf::uint64 rid() const; + void set_rid(::google::protobuf::uint64 value); + + // required uint64 Nodeid = 2; + bool has_nodeid() const; + void clear_nodeid(); + static const int kNodeidFieldNumber = 2; + ::google::protobuf::uint64 nodeid() const; + void set_nodeid(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:phxpaxos.PaxosNodeInfo) + private: + inline void set_has_rid(); + inline void clear_has_rid(); + inline void set_has_nodeid(); + inline void clear_has_nodeid(); + + // helper for ByteSize() + int RequiredFieldsByteSizeFallback() const; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 rid_; + ::google::protobuf::uint64 nodeid_; + friend void protobuf_AddDesc_paxos_5fmsg_2eproto(); + friend void protobuf_AssignDesc_paxos_5fmsg_2eproto(); + friend void protobuf_ShutdownFile_paxos_5fmsg_2eproto(); + + void InitAsDefaultInstance(); + static PaxosNodeInfo* default_instance_; +}; +// ------------------------------------------------------------------- + +class SystemVariables : public ::google::protobuf::Message { + public: + SystemVariables(); + virtual ~SystemVariables(); + + SystemVariables(const SystemVariables& from); + + inline SystemVariables& operator=(const SystemVariables& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SystemVariables& default_instance(); + + void Swap(SystemVariables* other); + + // implements Message ---------------------------------------------- + + inline SystemVariables* New() const { return New(NULL); } + + SystemVariables* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SystemVariables& from); + void MergeFrom(const SystemVariables& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(SystemVariables* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 Gid = 1; + bool has_gid() const; + void clear_gid(); + static const int kGidFieldNumber = 1; + ::google::protobuf::uint64 gid() const; + void set_gid(::google::protobuf::uint64 value); + + // repeated .phxpaxos.PaxosNodeInfo MemberShip = 2; + int membership_size() const; + void clear_membership(); + static const int kMemberShipFieldNumber = 2; + const ::phxpaxos::PaxosNodeInfo& membership(int index) const; + ::phxpaxos::PaxosNodeInfo* mutable_membership(int index); + ::phxpaxos::PaxosNodeInfo* add_membership(); + ::google::protobuf::RepeatedPtrField< ::phxpaxos::PaxosNodeInfo >* + mutable_membership(); + const ::google::protobuf::RepeatedPtrField< ::phxpaxos::PaxosNodeInfo >& + membership() const; + + // required uint64 Version = 3; + bool has_version() const; + void clear_version(); + static const int kVersionFieldNumber = 3; + ::google::protobuf::uint64 version() const; + void set_version(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:phxpaxos.SystemVariables) + private: + inline void set_has_gid(); + inline void clear_has_gid(); + inline void set_has_version(); + inline void clear_has_version(); + + // helper for ByteSize() + int RequiredFieldsByteSizeFallback() const; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 gid_; + ::google::protobuf::RepeatedPtrField< ::phxpaxos::PaxosNodeInfo > membership_; + ::google::protobuf::uint64 version_; + friend void protobuf_AddDesc_paxos_5fmsg_2eproto(); + friend void protobuf_AssignDesc_paxos_5fmsg_2eproto(); + friend void protobuf_ShutdownFile_paxos_5fmsg_2eproto(); + + void InitAsDefaultInstance(); + static SystemVariables* default_instance_; +}; +// ------------------------------------------------------------------- + +class MasterVariables : public ::google::protobuf::Message { + public: + MasterVariables(); + virtual ~MasterVariables(); + + MasterVariables(const MasterVariables& from); + + inline MasterVariables& operator=(const MasterVariables& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MasterVariables& default_instance(); + + void Swap(MasterVariables* other); + + // implements Message ---------------------------------------------- + + inline MasterVariables* New() const { return New(NULL); } + + MasterVariables* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MasterVariables& from); + void MergeFrom(const MasterVariables& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MasterVariables* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 MasterNodeid = 1; + bool has_masternodeid() const; + void clear_masternodeid(); + static const int kMasterNodeidFieldNumber = 1; + ::google::protobuf::uint64 masternodeid() const; + void set_masternodeid(::google::protobuf::uint64 value); + + // required uint64 Version = 2; + bool has_version() const; + void clear_version(); + static const int kVersionFieldNumber = 2; + ::google::protobuf::uint64 version() const; + void set_version(::google::protobuf::uint64 value); + + // required uint32 LeaseTime = 3; + bool has_leasetime() const; + void clear_leasetime(); + static const int kLeaseTimeFieldNumber = 3; + ::google::protobuf::uint32 leasetime() const; + void set_leasetime(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:phxpaxos.MasterVariables) + private: + inline void set_has_masternodeid(); + inline void clear_has_masternodeid(); + inline void set_has_version(); + inline void clear_has_version(); + inline void set_has_leasetime(); + inline void clear_has_leasetime(); + + // helper for ByteSize() + int RequiredFieldsByteSizeFallback() const; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 masternodeid_; + ::google::protobuf::uint64 version_; + ::google::protobuf::uint32 leasetime_; + friend void protobuf_AddDesc_paxos_5fmsg_2eproto(); + friend void protobuf_AssignDesc_paxos_5fmsg_2eproto(); + friend void protobuf_ShutdownFile_paxos_5fmsg_2eproto(); + + void InitAsDefaultInstance(); + static MasterVariables* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Header + +// required uint64 gid = 1; +inline bool Header::has_gid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void Header::set_has_gid() { + _has_bits_[0] |= 0x00000001u; +} +inline void Header::clear_has_gid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void Header::clear_gid() { + gid_ = GOOGLE_ULONGLONG(0); + clear_has_gid(); +} +inline ::google::protobuf::uint64 Header::gid() const { + // @@protoc_insertion_point(field_get:phxpaxos.Header.gid) + return gid_; +} +inline void Header::set_gid(::google::protobuf::uint64 value) { + set_has_gid(); + gid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.Header.gid) +} + +// required uint64 rid = 2; +inline bool Header::has_rid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void Header::set_has_rid() { + _has_bits_[0] |= 0x00000002u; +} +inline void Header::clear_has_rid() { + _has_bits_[0] &= ~0x00000002u; +} +inline void Header::clear_rid() { + rid_ = GOOGLE_ULONGLONG(0); + clear_has_rid(); +} +inline ::google::protobuf::uint64 Header::rid() const { + // @@protoc_insertion_point(field_get:phxpaxos.Header.rid) + return rid_; +} +inline void Header::set_rid(::google::protobuf::uint64 value) { + set_has_rid(); + rid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.Header.rid) +} + +// required int32 cmdid = 3; +inline bool Header::has_cmdid() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void Header::set_has_cmdid() { + _has_bits_[0] |= 0x00000004u; +} +inline void Header::clear_has_cmdid() { + _has_bits_[0] &= ~0x00000004u; +} +inline void Header::clear_cmdid() { + cmdid_ = 0; + clear_has_cmdid(); +} +inline ::google::protobuf::int32 Header::cmdid() const { + // @@protoc_insertion_point(field_get:phxpaxos.Header.cmdid) + return cmdid_; +} +inline void Header::set_cmdid(::google::protobuf::int32 value) { + set_has_cmdid(); + cmdid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.Header.cmdid) +} + +// optional int32 version = 4; +inline bool Header::has_version() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void Header::set_has_version() { + _has_bits_[0] |= 0x00000008u; +} +inline void Header::clear_has_version() { + _has_bits_[0] &= ~0x00000008u; +} +inline void Header::clear_version() { + version_ = 0; + clear_has_version(); +} +inline ::google::protobuf::int32 Header::version() const { + // @@protoc_insertion_point(field_get:phxpaxos.Header.version) + return version_; +} +inline void Header::set_version(::google::protobuf::int32 value) { + set_has_version(); + version_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.Header.version) +} + +// ------------------------------------------------------------------- + +// PaxosMsg + +// required int32 MsgType = 1; +inline bool PaxosMsg::has_msgtype() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void PaxosMsg::set_has_msgtype() { + _has_bits_[0] |= 0x00000001u; +} +inline void PaxosMsg::clear_has_msgtype() { + _has_bits_[0] &= ~0x00000001u; +} +inline void PaxosMsg::clear_msgtype() { + msgtype_ = 0; + clear_has_msgtype(); +} +inline ::google::protobuf::int32 PaxosMsg::msgtype() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.MsgType) + return msgtype_; +} +inline void PaxosMsg::set_msgtype(::google::protobuf::int32 value) { + set_has_msgtype(); + msgtype_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.MsgType) +} + +// optional uint64 InstanceID = 2; +inline bool PaxosMsg::has_instanceid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void PaxosMsg::set_has_instanceid() { + _has_bits_[0] |= 0x00000002u; +} +inline void PaxosMsg::clear_has_instanceid() { + _has_bits_[0] &= ~0x00000002u; +} +inline void PaxosMsg::clear_instanceid() { + instanceid_ = GOOGLE_ULONGLONG(0); + clear_has_instanceid(); +} +inline ::google::protobuf::uint64 PaxosMsg::instanceid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.InstanceID) + return instanceid_; +} +inline void PaxosMsg::set_instanceid(::google::protobuf::uint64 value) { + set_has_instanceid(); + instanceid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.InstanceID) +} + +// optional uint64 NodeID = 3; +inline bool PaxosMsg::has_nodeid() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void PaxosMsg::set_has_nodeid() { + _has_bits_[0] |= 0x00000004u; +} +inline void PaxosMsg::clear_has_nodeid() { + _has_bits_[0] &= ~0x00000004u; +} +inline void PaxosMsg::clear_nodeid() { + nodeid_ = GOOGLE_ULONGLONG(0); + clear_has_nodeid(); +} +inline ::google::protobuf::uint64 PaxosMsg::nodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.NodeID) + return nodeid_; +} +inline void PaxosMsg::set_nodeid(::google::protobuf::uint64 value) { + set_has_nodeid(); + nodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.NodeID) +} + +// optional uint64 ProposalID = 4; +inline bool PaxosMsg::has_proposalid() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void PaxosMsg::set_has_proposalid() { + _has_bits_[0] |= 0x00000008u; +} +inline void PaxosMsg::clear_has_proposalid() { + _has_bits_[0] &= ~0x00000008u; +} +inline void PaxosMsg::clear_proposalid() { + proposalid_ = GOOGLE_ULONGLONG(0); + clear_has_proposalid(); +} +inline ::google::protobuf::uint64 PaxosMsg::proposalid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.ProposalID) + return proposalid_; +} +inline void PaxosMsg::set_proposalid(::google::protobuf::uint64 value) { + set_has_proposalid(); + proposalid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.ProposalID) +} + +// optional uint64 ProposalNodeID = 5; +inline bool PaxosMsg::has_proposalnodeid() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void PaxosMsg::set_has_proposalnodeid() { + _has_bits_[0] |= 0x00000010u; +} +inline void PaxosMsg::clear_has_proposalnodeid() { + _has_bits_[0] &= ~0x00000010u; +} +inline void PaxosMsg::clear_proposalnodeid() { + proposalnodeid_ = GOOGLE_ULONGLONG(0); + clear_has_proposalnodeid(); +} +inline ::google::protobuf::uint64 PaxosMsg::proposalnodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.ProposalNodeID) + return proposalnodeid_; +} +inline void PaxosMsg::set_proposalnodeid(::google::protobuf::uint64 value) { + set_has_proposalnodeid(); + proposalnodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.ProposalNodeID) +} + +// optional bytes Value = 6; +inline bool PaxosMsg::has_value() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void PaxosMsg::set_has_value() { + _has_bits_[0] |= 0x00000020u; +} +inline void PaxosMsg::clear_has_value() { + _has_bits_[0] &= ~0x00000020u; +} +inline void PaxosMsg::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_value(); +} +inline const ::std::string& PaxosMsg::value() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.Value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void PaxosMsg::set_value(const ::std::string& value) { + set_has_value(); + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.Value) +} +inline void PaxosMsg::set_value(const char* value) { + set_has_value(); + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.PaxosMsg.Value) +} +inline void PaxosMsg::set_value(const void* value, size_t size) { + set_has_value(); + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.PaxosMsg.Value) +} +inline ::std::string* PaxosMsg::mutable_value() { + set_has_value(); + // @@protoc_insertion_point(field_mutable:phxpaxos.PaxosMsg.Value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* PaxosMsg::release_value() { + clear_has_value(); + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void PaxosMsg::set_allocated_value(::std::string* value) { + if (value != NULL) { + set_has_value(); + } else { + clear_has_value(); + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.PaxosMsg.Value) +} + +// optional uint64 PreAcceptID = 7; +inline bool PaxosMsg::has_preacceptid() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void PaxosMsg::set_has_preacceptid() { + _has_bits_[0] |= 0x00000040u; +} +inline void PaxosMsg::clear_has_preacceptid() { + _has_bits_[0] &= ~0x00000040u; +} +inline void PaxosMsg::clear_preacceptid() { + preacceptid_ = GOOGLE_ULONGLONG(0); + clear_has_preacceptid(); +} +inline ::google::protobuf::uint64 PaxosMsg::preacceptid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.PreAcceptID) + return preacceptid_; +} +inline void PaxosMsg::set_preacceptid(::google::protobuf::uint64 value) { + set_has_preacceptid(); + preacceptid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.PreAcceptID) +} + +// optional uint64 PreAcceptNodeID = 8; +inline bool PaxosMsg::has_preacceptnodeid() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void PaxosMsg::set_has_preacceptnodeid() { + _has_bits_[0] |= 0x00000080u; +} +inline void PaxosMsg::clear_has_preacceptnodeid() { + _has_bits_[0] &= ~0x00000080u; +} +inline void PaxosMsg::clear_preacceptnodeid() { + preacceptnodeid_ = GOOGLE_ULONGLONG(0); + clear_has_preacceptnodeid(); +} +inline ::google::protobuf::uint64 PaxosMsg::preacceptnodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.PreAcceptNodeID) + return preacceptnodeid_; +} +inline void PaxosMsg::set_preacceptnodeid(::google::protobuf::uint64 value) { + set_has_preacceptnodeid(); + preacceptnodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.PreAcceptNodeID) +} + +// optional uint64 RejectByPromiseID = 9; +inline bool PaxosMsg::has_rejectbypromiseid() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void PaxosMsg::set_has_rejectbypromiseid() { + _has_bits_[0] |= 0x00000100u; +} +inline void PaxosMsg::clear_has_rejectbypromiseid() { + _has_bits_[0] &= ~0x00000100u; +} +inline void PaxosMsg::clear_rejectbypromiseid() { + rejectbypromiseid_ = GOOGLE_ULONGLONG(0); + clear_has_rejectbypromiseid(); +} +inline ::google::protobuf::uint64 PaxosMsg::rejectbypromiseid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.RejectByPromiseID) + return rejectbypromiseid_; +} +inline void PaxosMsg::set_rejectbypromiseid(::google::protobuf::uint64 value) { + set_has_rejectbypromiseid(); + rejectbypromiseid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.RejectByPromiseID) +} + +// optional uint64 NowInstanceID = 10; +inline bool PaxosMsg::has_nowinstanceid() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void PaxosMsg::set_has_nowinstanceid() { + _has_bits_[0] |= 0x00000200u; +} +inline void PaxosMsg::clear_has_nowinstanceid() { + _has_bits_[0] &= ~0x00000200u; +} +inline void PaxosMsg::clear_nowinstanceid() { + nowinstanceid_ = GOOGLE_ULONGLONG(0); + clear_has_nowinstanceid(); +} +inline ::google::protobuf::uint64 PaxosMsg::nowinstanceid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.NowInstanceID) + return nowinstanceid_; +} +inline void PaxosMsg::set_nowinstanceid(::google::protobuf::uint64 value) { + set_has_nowinstanceid(); + nowinstanceid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.NowInstanceID) +} + +// optional uint64 MinChosenInstanceID = 11; +inline bool PaxosMsg::has_minchoseninstanceid() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void PaxosMsg::set_has_minchoseninstanceid() { + _has_bits_[0] |= 0x00000400u; +} +inline void PaxosMsg::clear_has_minchoseninstanceid() { + _has_bits_[0] &= ~0x00000400u; +} +inline void PaxosMsg::clear_minchoseninstanceid() { + minchoseninstanceid_ = GOOGLE_ULONGLONG(0); + clear_has_minchoseninstanceid(); +} +inline ::google::protobuf::uint64 PaxosMsg::minchoseninstanceid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.MinChosenInstanceID) + return minchoseninstanceid_; +} +inline void PaxosMsg::set_minchoseninstanceid(::google::protobuf::uint64 value) { + set_has_minchoseninstanceid(); + minchoseninstanceid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.MinChosenInstanceID) +} + +// optional uint32 LastChecksum = 12; +inline bool PaxosMsg::has_lastchecksum() const { + return (_has_bits_[0] & 0x00000800u) != 0; +} +inline void PaxosMsg::set_has_lastchecksum() { + _has_bits_[0] |= 0x00000800u; +} +inline void PaxosMsg::clear_has_lastchecksum() { + _has_bits_[0] &= ~0x00000800u; +} +inline void PaxosMsg::clear_lastchecksum() { + lastchecksum_ = 0u; + clear_has_lastchecksum(); +} +inline ::google::protobuf::uint32 PaxosMsg::lastchecksum() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.LastChecksum) + return lastchecksum_; +} +inline void PaxosMsg::set_lastchecksum(::google::protobuf::uint32 value) { + set_has_lastchecksum(); + lastchecksum_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.LastChecksum) +} + +// optional uint32 Flag = 13; +inline bool PaxosMsg::has_flag() const { + return (_has_bits_[0] & 0x00001000u) != 0; +} +inline void PaxosMsg::set_has_flag() { + _has_bits_[0] |= 0x00001000u; +} +inline void PaxosMsg::clear_has_flag() { + _has_bits_[0] &= ~0x00001000u; +} +inline void PaxosMsg::clear_flag() { + flag_ = 0u; + clear_has_flag(); +} +inline ::google::protobuf::uint32 PaxosMsg::flag() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.Flag) + return flag_; +} +inline void PaxosMsg::set_flag(::google::protobuf::uint32 value) { + set_has_flag(); + flag_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.Flag) +} + +// optional bytes SystemVariables = 14; +inline bool PaxosMsg::has_systemvariables() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +inline void PaxosMsg::set_has_systemvariables() { + _has_bits_[0] |= 0x00002000u; +} +inline void PaxosMsg::clear_has_systemvariables() { + _has_bits_[0] &= ~0x00002000u; +} +inline void PaxosMsg::clear_systemvariables() { + systemvariables_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_systemvariables(); +} +inline const ::std::string& PaxosMsg::systemvariables() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.SystemVariables) + return systemvariables_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void PaxosMsg::set_systemvariables(const ::std::string& value) { + set_has_systemvariables(); + systemvariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.SystemVariables) +} +inline void PaxosMsg::set_systemvariables(const char* value) { + set_has_systemvariables(); + systemvariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.PaxosMsg.SystemVariables) +} +inline void PaxosMsg::set_systemvariables(const void* value, size_t size) { + set_has_systemvariables(); + systemvariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.PaxosMsg.SystemVariables) +} +inline ::std::string* PaxosMsg::mutable_systemvariables() { + set_has_systemvariables(); + // @@protoc_insertion_point(field_mutable:phxpaxos.PaxosMsg.SystemVariables) + return systemvariables_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* PaxosMsg::release_systemvariables() { + clear_has_systemvariables(); + return systemvariables_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void PaxosMsg::set_allocated_systemvariables(::std::string* systemvariables) { + if (systemvariables != NULL) { + set_has_systemvariables(); + } else { + clear_has_systemvariables(); + } + systemvariables_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), systemvariables); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.PaxosMsg.SystemVariables) +} + +// optional bytes MasterVariables = 15; +inline bool PaxosMsg::has_mastervariables() const { + return (_has_bits_[0] & 0x00004000u) != 0; +} +inline void PaxosMsg::set_has_mastervariables() { + _has_bits_[0] |= 0x00004000u; +} +inline void PaxosMsg::clear_has_mastervariables() { + _has_bits_[0] &= ~0x00004000u; +} +inline void PaxosMsg::clear_mastervariables() { + mastervariables_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_mastervariables(); +} +inline const ::std::string& PaxosMsg::mastervariables() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosMsg.MasterVariables) + return mastervariables_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void PaxosMsg::set_mastervariables(const ::std::string& value) { + set_has_mastervariables(); + mastervariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.PaxosMsg.MasterVariables) +} +inline void PaxosMsg::set_mastervariables(const char* value) { + set_has_mastervariables(); + mastervariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.PaxosMsg.MasterVariables) +} +inline void PaxosMsg::set_mastervariables(const void* value, size_t size) { + set_has_mastervariables(); + mastervariables_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.PaxosMsg.MasterVariables) +} +inline ::std::string* PaxosMsg::mutable_mastervariables() { + set_has_mastervariables(); + // @@protoc_insertion_point(field_mutable:phxpaxos.PaxosMsg.MasterVariables) + return mastervariables_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* PaxosMsg::release_mastervariables() { + clear_has_mastervariables(); + return mastervariables_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void PaxosMsg::set_allocated_mastervariables(::std::string* mastervariables) { + if (mastervariables != NULL) { + set_has_mastervariables(); + } else { + clear_has_mastervariables(); + } + mastervariables_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), mastervariables); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.PaxosMsg.MasterVariables) +} + +// ------------------------------------------------------------------- + +// CheckpointMsg + +// required int32 MsgType = 1; +inline bool CheckpointMsg::has_msgtype() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CheckpointMsg::set_has_msgtype() { + _has_bits_[0] |= 0x00000001u; +} +inline void CheckpointMsg::clear_has_msgtype() { + _has_bits_[0] &= ~0x00000001u; +} +inline void CheckpointMsg::clear_msgtype() { + msgtype_ = 0; + clear_has_msgtype(); +} +inline ::google::protobuf::int32 CheckpointMsg::msgtype() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.MsgType) + return msgtype_; +} +inline void CheckpointMsg::set_msgtype(::google::protobuf::int32 value) { + set_has_msgtype(); + msgtype_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.MsgType) +} + +// required uint64 NodeID = 2; +inline bool CheckpointMsg::has_nodeid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CheckpointMsg::set_has_nodeid() { + _has_bits_[0] |= 0x00000002u; +} +inline void CheckpointMsg::clear_has_nodeid() { + _has_bits_[0] &= ~0x00000002u; +} +inline void CheckpointMsg::clear_nodeid() { + nodeid_ = GOOGLE_ULONGLONG(0); + clear_has_nodeid(); +} +inline ::google::protobuf::uint64 CheckpointMsg::nodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.NodeID) + return nodeid_; +} +inline void CheckpointMsg::set_nodeid(::google::protobuf::uint64 value) { + set_has_nodeid(); + nodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.NodeID) +} + +// optional int32 Flag = 3; +inline bool CheckpointMsg::has_flag() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CheckpointMsg::set_has_flag() { + _has_bits_[0] |= 0x00000004u; +} +inline void CheckpointMsg::clear_has_flag() { + _has_bits_[0] &= ~0x00000004u; +} +inline void CheckpointMsg::clear_flag() { + flag_ = 0; + clear_has_flag(); +} +inline ::google::protobuf::int32 CheckpointMsg::flag() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.Flag) + return flag_; +} +inline void CheckpointMsg::set_flag(::google::protobuf::int32 value) { + set_has_flag(); + flag_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.Flag) +} + +// required uint64 UUID = 4; +inline bool CheckpointMsg::has_uuid() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void CheckpointMsg::set_has_uuid() { + _has_bits_[0] |= 0x00000008u; +} +inline void CheckpointMsg::clear_has_uuid() { + _has_bits_[0] &= ~0x00000008u; +} +inline void CheckpointMsg::clear_uuid() { + uuid_ = GOOGLE_ULONGLONG(0); + clear_has_uuid(); +} +inline ::google::protobuf::uint64 CheckpointMsg::uuid() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.UUID) + return uuid_; +} +inline void CheckpointMsg::set_uuid(::google::protobuf::uint64 value) { + set_has_uuid(); + uuid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.UUID) +} + +// required uint64 Sequence = 5; +inline bool CheckpointMsg::has_sequence() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void CheckpointMsg::set_has_sequence() { + _has_bits_[0] |= 0x00000010u; +} +inline void CheckpointMsg::clear_has_sequence() { + _has_bits_[0] &= ~0x00000010u; +} +inline void CheckpointMsg::clear_sequence() { + sequence_ = GOOGLE_ULONGLONG(0); + clear_has_sequence(); +} +inline ::google::protobuf::uint64 CheckpointMsg::sequence() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.Sequence) + return sequence_; +} +inline void CheckpointMsg::set_sequence(::google::protobuf::uint64 value) { + set_has_sequence(); + sequence_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.Sequence) +} + +// optional uint64 CheckpointInstanceID = 6; +inline bool CheckpointMsg::has_checkpointinstanceid() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void CheckpointMsg::set_has_checkpointinstanceid() { + _has_bits_[0] |= 0x00000020u; +} +inline void CheckpointMsg::clear_has_checkpointinstanceid() { + _has_bits_[0] &= ~0x00000020u; +} +inline void CheckpointMsg::clear_checkpointinstanceid() { + checkpointinstanceid_ = GOOGLE_ULONGLONG(0); + clear_has_checkpointinstanceid(); +} +inline ::google::protobuf::uint64 CheckpointMsg::checkpointinstanceid() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.CheckpointInstanceID) + return checkpointinstanceid_; +} +inline void CheckpointMsg::set_checkpointinstanceid(::google::protobuf::uint64 value) { + set_has_checkpointinstanceid(); + checkpointinstanceid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.CheckpointInstanceID) +} + +// optional uint32 Checksum = 7; +inline bool CheckpointMsg::has_checksum() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void CheckpointMsg::set_has_checksum() { + _has_bits_[0] |= 0x00000040u; +} +inline void CheckpointMsg::clear_has_checksum() { + _has_bits_[0] &= ~0x00000040u; +} +inline void CheckpointMsg::clear_checksum() { + checksum_ = 0u; + clear_has_checksum(); +} +inline ::google::protobuf::uint32 CheckpointMsg::checksum() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.Checksum) + return checksum_; +} +inline void CheckpointMsg::set_checksum(::google::protobuf::uint32 value) { + set_has_checksum(); + checksum_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.Checksum) +} + +// optional string FilePath = 8; +inline bool CheckpointMsg::has_filepath() const { + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void CheckpointMsg::set_has_filepath() { + _has_bits_[0] |= 0x00000080u; +} +inline void CheckpointMsg::clear_has_filepath() { + _has_bits_[0] &= ~0x00000080u; +} +inline void CheckpointMsg::clear_filepath() { + filepath_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_filepath(); +} +inline const ::std::string& CheckpointMsg::filepath() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.FilePath) + return filepath_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CheckpointMsg::set_filepath(const ::std::string& value) { + set_has_filepath(); + filepath_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.FilePath) +} +inline void CheckpointMsg::set_filepath(const char* value) { + set_has_filepath(); + filepath_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.CheckpointMsg.FilePath) +} +inline void CheckpointMsg::set_filepath(const char* value, size_t size) { + set_has_filepath(); + filepath_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.CheckpointMsg.FilePath) +} +inline ::std::string* CheckpointMsg::mutable_filepath() { + set_has_filepath(); + // @@protoc_insertion_point(field_mutable:phxpaxos.CheckpointMsg.FilePath) + return filepath_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CheckpointMsg::release_filepath() { + clear_has_filepath(); + return filepath_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CheckpointMsg::set_allocated_filepath(::std::string* filepath) { + if (filepath != NULL) { + set_has_filepath(); + } else { + clear_has_filepath(); + } + filepath_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), filepath); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.CheckpointMsg.FilePath) +} + +// optional int32 SMID = 9; +inline bool CheckpointMsg::has_smid() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void CheckpointMsg::set_has_smid() { + _has_bits_[0] |= 0x00000100u; +} +inline void CheckpointMsg::clear_has_smid() { + _has_bits_[0] &= ~0x00000100u; +} +inline void CheckpointMsg::clear_smid() { + smid_ = 0; + clear_has_smid(); +} +inline ::google::protobuf::int32 CheckpointMsg::smid() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.SMID) + return smid_; +} +inline void CheckpointMsg::set_smid(::google::protobuf::int32 value) { + set_has_smid(); + smid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.SMID) +} + +// optional uint64 Offset = 10; +inline bool CheckpointMsg::has_offset() const { + return (_has_bits_[0] & 0x00000200u) != 0; +} +inline void CheckpointMsg::set_has_offset() { + _has_bits_[0] |= 0x00000200u; +} +inline void CheckpointMsg::clear_has_offset() { + _has_bits_[0] &= ~0x00000200u; +} +inline void CheckpointMsg::clear_offset() { + offset_ = GOOGLE_ULONGLONG(0); + clear_has_offset(); +} +inline ::google::protobuf::uint64 CheckpointMsg::offset() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.Offset) + return offset_; +} +inline void CheckpointMsg::set_offset(::google::protobuf::uint64 value) { + set_has_offset(); + offset_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.Offset) +} + +// optional bytes Buffer = 11; +inline bool CheckpointMsg::has_buffer() const { + return (_has_bits_[0] & 0x00000400u) != 0; +} +inline void CheckpointMsg::set_has_buffer() { + _has_bits_[0] |= 0x00000400u; +} +inline void CheckpointMsg::clear_has_buffer() { + _has_bits_[0] &= ~0x00000400u; +} +inline void CheckpointMsg::clear_buffer() { + buffer_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_buffer(); +} +inline const ::std::string& CheckpointMsg::buffer() const { + // @@protoc_insertion_point(field_get:phxpaxos.CheckpointMsg.Buffer) + return buffer_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CheckpointMsg::set_buffer(const ::std::string& value) { + set_has_buffer(); + buffer_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.CheckpointMsg.Buffer) +} +inline void CheckpointMsg::set_buffer(const char* value) { + set_has_buffer(); + buffer_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.CheckpointMsg.Buffer) +} +inline void CheckpointMsg::set_buffer(const void* value, size_t size) { + set_has_buffer(); + buffer_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.CheckpointMsg.Buffer) +} +inline ::std::string* CheckpointMsg::mutable_buffer() { + set_has_buffer(); + // @@protoc_insertion_point(field_mutable:phxpaxos.CheckpointMsg.Buffer) + return buffer_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* CheckpointMsg::release_buffer() { + clear_has_buffer(); + return buffer_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void CheckpointMsg::set_allocated_buffer(::std::string* buffer) { + if (buffer != NULL) { + set_has_buffer(); + } else { + clear_has_buffer(); + } + buffer_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), buffer); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.CheckpointMsg.Buffer) +} + +// ------------------------------------------------------------------- + +// AcceptorStateData + +// required uint64 InstanceID = 1; +inline bool AcceptorStateData::has_instanceid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void AcceptorStateData::set_has_instanceid() { + _has_bits_[0] |= 0x00000001u; +} +inline void AcceptorStateData::clear_has_instanceid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void AcceptorStateData::clear_instanceid() { + instanceid_ = GOOGLE_ULONGLONG(0); + clear_has_instanceid(); +} +inline ::google::protobuf::uint64 AcceptorStateData::instanceid() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.InstanceID) + return instanceid_; +} +inline void AcceptorStateData::set_instanceid(::google::protobuf::uint64 value) { + set_has_instanceid(); + instanceid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.InstanceID) +} + +// required uint64 PromiseID = 2; +inline bool AcceptorStateData::has_promiseid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void AcceptorStateData::set_has_promiseid() { + _has_bits_[0] |= 0x00000002u; +} +inline void AcceptorStateData::clear_has_promiseid() { + _has_bits_[0] &= ~0x00000002u; +} +inline void AcceptorStateData::clear_promiseid() { + promiseid_ = GOOGLE_ULONGLONG(0); + clear_has_promiseid(); +} +inline ::google::protobuf::uint64 AcceptorStateData::promiseid() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.PromiseID) + return promiseid_; +} +inline void AcceptorStateData::set_promiseid(::google::protobuf::uint64 value) { + set_has_promiseid(); + promiseid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.PromiseID) +} + +// required uint64 PromiseNodeID = 3; +inline bool AcceptorStateData::has_promisenodeid() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void AcceptorStateData::set_has_promisenodeid() { + _has_bits_[0] |= 0x00000004u; +} +inline void AcceptorStateData::clear_has_promisenodeid() { + _has_bits_[0] &= ~0x00000004u; +} +inline void AcceptorStateData::clear_promisenodeid() { + promisenodeid_ = GOOGLE_ULONGLONG(0); + clear_has_promisenodeid(); +} +inline ::google::protobuf::uint64 AcceptorStateData::promisenodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.PromiseNodeID) + return promisenodeid_; +} +inline void AcceptorStateData::set_promisenodeid(::google::protobuf::uint64 value) { + set_has_promisenodeid(); + promisenodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.PromiseNodeID) +} + +// required uint64 AcceptedID = 4; +inline bool AcceptorStateData::has_acceptedid() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void AcceptorStateData::set_has_acceptedid() { + _has_bits_[0] |= 0x00000008u; +} +inline void AcceptorStateData::clear_has_acceptedid() { + _has_bits_[0] &= ~0x00000008u; +} +inline void AcceptorStateData::clear_acceptedid() { + acceptedid_ = GOOGLE_ULONGLONG(0); + clear_has_acceptedid(); +} +inline ::google::protobuf::uint64 AcceptorStateData::acceptedid() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.AcceptedID) + return acceptedid_; +} +inline void AcceptorStateData::set_acceptedid(::google::protobuf::uint64 value) { + set_has_acceptedid(); + acceptedid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.AcceptedID) +} + +// required uint64 AcceptedNodeID = 5; +inline bool AcceptorStateData::has_acceptednodeid() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void AcceptorStateData::set_has_acceptednodeid() { + _has_bits_[0] |= 0x00000010u; +} +inline void AcceptorStateData::clear_has_acceptednodeid() { + _has_bits_[0] &= ~0x00000010u; +} +inline void AcceptorStateData::clear_acceptednodeid() { + acceptednodeid_ = GOOGLE_ULONGLONG(0); + clear_has_acceptednodeid(); +} +inline ::google::protobuf::uint64 AcceptorStateData::acceptednodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.AcceptedNodeID) + return acceptednodeid_; +} +inline void AcceptorStateData::set_acceptednodeid(::google::protobuf::uint64 value) { + set_has_acceptednodeid(); + acceptednodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.AcceptedNodeID) +} + +// required bytes AcceptedValue = 6; +inline bool AcceptorStateData::has_acceptedvalue() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void AcceptorStateData::set_has_acceptedvalue() { + _has_bits_[0] |= 0x00000020u; +} +inline void AcceptorStateData::clear_has_acceptedvalue() { + _has_bits_[0] &= ~0x00000020u; +} +inline void AcceptorStateData::clear_acceptedvalue() { + acceptedvalue_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_acceptedvalue(); +} +inline const ::std::string& AcceptorStateData::acceptedvalue() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.AcceptedValue) + return acceptedvalue_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void AcceptorStateData::set_acceptedvalue(const ::std::string& value) { + set_has_acceptedvalue(); + acceptedvalue_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.AcceptedValue) +} +inline void AcceptorStateData::set_acceptedvalue(const char* value) { + set_has_acceptedvalue(); + acceptedvalue_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:phxpaxos.AcceptorStateData.AcceptedValue) +} +inline void AcceptorStateData::set_acceptedvalue(const void* value, size_t size) { + set_has_acceptedvalue(); + acceptedvalue_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:phxpaxos.AcceptorStateData.AcceptedValue) +} +inline ::std::string* AcceptorStateData::mutable_acceptedvalue() { + set_has_acceptedvalue(); + // @@protoc_insertion_point(field_mutable:phxpaxos.AcceptorStateData.AcceptedValue) + return acceptedvalue_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* AcceptorStateData::release_acceptedvalue() { + clear_has_acceptedvalue(); + return acceptedvalue_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void AcceptorStateData::set_allocated_acceptedvalue(::std::string* acceptedvalue) { + if (acceptedvalue != NULL) { + set_has_acceptedvalue(); + } else { + clear_has_acceptedvalue(); + } + acceptedvalue_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), acceptedvalue); + // @@protoc_insertion_point(field_set_allocated:phxpaxos.AcceptorStateData.AcceptedValue) +} + +// required uint32 Checksum = 7; +inline bool AcceptorStateData::has_checksum() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void AcceptorStateData::set_has_checksum() { + _has_bits_[0] |= 0x00000040u; +} +inline void AcceptorStateData::clear_has_checksum() { + _has_bits_[0] &= ~0x00000040u; +} +inline void AcceptorStateData::clear_checksum() { + checksum_ = 0u; + clear_has_checksum(); +} +inline ::google::protobuf::uint32 AcceptorStateData::checksum() const { + // @@protoc_insertion_point(field_get:phxpaxos.AcceptorStateData.Checksum) + return checksum_; +} +inline void AcceptorStateData::set_checksum(::google::protobuf::uint32 value) { + set_has_checksum(); + checksum_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.AcceptorStateData.Checksum) +} + +// ------------------------------------------------------------------- + +// PaxosNodeInfo + +// required uint64 Rid = 1; +inline bool PaxosNodeInfo::has_rid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void PaxosNodeInfo::set_has_rid() { + _has_bits_[0] |= 0x00000001u; +} +inline void PaxosNodeInfo::clear_has_rid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void PaxosNodeInfo::clear_rid() { + rid_ = GOOGLE_ULONGLONG(0); + clear_has_rid(); +} +inline ::google::protobuf::uint64 PaxosNodeInfo::rid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosNodeInfo.Rid) + return rid_; +} +inline void PaxosNodeInfo::set_rid(::google::protobuf::uint64 value) { + set_has_rid(); + rid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosNodeInfo.Rid) +} + +// required uint64 Nodeid = 2; +inline bool PaxosNodeInfo::has_nodeid() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void PaxosNodeInfo::set_has_nodeid() { + _has_bits_[0] |= 0x00000002u; +} +inline void PaxosNodeInfo::clear_has_nodeid() { + _has_bits_[0] &= ~0x00000002u; +} +inline void PaxosNodeInfo::clear_nodeid() { + nodeid_ = GOOGLE_ULONGLONG(0); + clear_has_nodeid(); +} +inline ::google::protobuf::uint64 PaxosNodeInfo::nodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.PaxosNodeInfo.Nodeid) + return nodeid_; +} +inline void PaxosNodeInfo::set_nodeid(::google::protobuf::uint64 value) { + set_has_nodeid(); + nodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.PaxosNodeInfo.Nodeid) +} + +// ------------------------------------------------------------------- + +// SystemVariables + +// required uint64 Gid = 1; +inline bool SystemVariables::has_gid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void SystemVariables::set_has_gid() { + _has_bits_[0] |= 0x00000001u; +} +inline void SystemVariables::clear_has_gid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void SystemVariables::clear_gid() { + gid_ = GOOGLE_ULONGLONG(0); + clear_has_gid(); +} +inline ::google::protobuf::uint64 SystemVariables::gid() const { + // @@protoc_insertion_point(field_get:phxpaxos.SystemVariables.Gid) + return gid_; +} +inline void SystemVariables::set_gid(::google::protobuf::uint64 value) { + set_has_gid(); + gid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.SystemVariables.Gid) +} + +// repeated .phxpaxos.PaxosNodeInfo MemberShip = 2; +inline int SystemVariables::membership_size() const { + return membership_.size(); +} +inline void SystemVariables::clear_membership() { + membership_.Clear(); +} +inline const ::phxpaxos::PaxosNodeInfo& SystemVariables::membership(int index) const { + // @@protoc_insertion_point(field_get:phxpaxos.SystemVariables.MemberShip) + return membership_.Get(index); +} +inline ::phxpaxos::PaxosNodeInfo* SystemVariables::mutable_membership(int index) { + // @@protoc_insertion_point(field_mutable:phxpaxos.SystemVariables.MemberShip) + return membership_.Mutable(index); +} +inline ::phxpaxos::PaxosNodeInfo* SystemVariables::add_membership() { + // @@protoc_insertion_point(field_add:phxpaxos.SystemVariables.MemberShip) + return membership_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::phxpaxos::PaxosNodeInfo >* +SystemVariables::mutable_membership() { + // @@protoc_insertion_point(field_mutable_list:phxpaxos.SystemVariables.MemberShip) + return &membership_; +} +inline const ::google::protobuf::RepeatedPtrField< ::phxpaxos::PaxosNodeInfo >& +SystemVariables::membership() const { + // @@protoc_insertion_point(field_list:phxpaxos.SystemVariables.MemberShip) + return membership_; +} + +// required uint64 Version = 3; +inline bool SystemVariables::has_version() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void SystemVariables::set_has_version() { + _has_bits_[0] |= 0x00000004u; +} +inline void SystemVariables::clear_has_version() { + _has_bits_[0] &= ~0x00000004u; +} +inline void SystemVariables::clear_version() { + version_ = GOOGLE_ULONGLONG(0); + clear_has_version(); +} +inline ::google::protobuf::uint64 SystemVariables::version() const { + // @@protoc_insertion_point(field_get:phxpaxos.SystemVariables.Version) + return version_; +} +inline void SystemVariables::set_version(::google::protobuf::uint64 value) { + set_has_version(); + version_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.SystemVariables.Version) +} + +// ------------------------------------------------------------------- + +// MasterVariables + +// required uint64 MasterNodeid = 1; +inline bool MasterVariables::has_masternodeid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MasterVariables::set_has_masternodeid() { + _has_bits_[0] |= 0x00000001u; +} +inline void MasterVariables::clear_has_masternodeid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MasterVariables::clear_masternodeid() { + masternodeid_ = GOOGLE_ULONGLONG(0); + clear_has_masternodeid(); +} +inline ::google::protobuf::uint64 MasterVariables::masternodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterVariables.MasterNodeid) + return masternodeid_; +} +inline void MasterVariables::set_masternodeid(::google::protobuf::uint64 value) { + set_has_masternodeid(); + masternodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterVariables.MasterNodeid) +} + +// required uint64 Version = 2; +inline bool MasterVariables::has_version() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MasterVariables::set_has_version() { + _has_bits_[0] |= 0x00000002u; +} +inline void MasterVariables::clear_has_version() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MasterVariables::clear_version() { + version_ = GOOGLE_ULONGLONG(0); + clear_has_version(); +} +inline ::google::protobuf::uint64 MasterVariables::version() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterVariables.Version) + return version_; +} +inline void MasterVariables::set_version(::google::protobuf::uint64 value) { + set_has_version(); + version_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterVariables.Version) +} + +// required uint32 LeaseTime = 3; +inline bool MasterVariables::has_leasetime() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MasterVariables::set_has_leasetime() { + _has_bits_[0] |= 0x00000004u; +} +inline void MasterVariables::clear_has_leasetime() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MasterVariables::clear_leasetime() { + leasetime_ = 0u; + clear_has_leasetime(); +} +inline ::google::protobuf::uint32 MasterVariables::leasetime() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterVariables.LeaseTime) + return leasetime_; +} +inline void MasterVariables::set_leasetime(::google::protobuf::uint32 value) { + set_has_leasetime(); + leasetime_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterVariables.LeaseTime) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace phxpaxos + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_paxos_5fmsg_2eproto__INCLUDED diff --git a/src/comm/paxos_msg.proto b/src/comm/paxos_msg.proto new file mode 100644 index 000000000..718f77525 --- /dev/null +++ b/src/comm/paxos_msg.proto @@ -0,0 +1,77 @@ +// Copyright (c) 2016 The Paxoslib Authors(lynncui@tencent). All rights reserved. + +syntax = "proto2"; +package phxpaxos; + +message Header +{ + required uint64 gid = 1; + required uint64 rid = 2; + required int32 cmdid = 3; + optional int32 version = 4; +}; + +message PaxosMsg +{ + required int32 MsgType = 1; + optional uint64 InstanceID = 2; + optional uint64 NodeID = 3; + optional uint64 ProposalID = 4; + optional uint64 ProposalNodeID = 5; + optional bytes Value = 6; + optional uint64 PreAcceptID = 7; + optional uint64 PreAcceptNodeID = 8; + optional uint64 RejectByPromiseID = 9; + optional uint64 NowInstanceID = 10; + optional uint64 MinChosenInstanceID = 11; + optional uint32 LastChecksum = 12; + optional uint32 Flag = 13; + optional bytes SystemVariables = 14; + optional bytes MasterVariables = 15; +}; + +message CheckpointMsg +{ + required int32 MsgType = 1; + required uint64 NodeID = 2; + optional int32 Flag = 3; + required uint64 UUID = 4; + required uint64 Sequence = 5; + optional uint64 CheckpointInstanceID = 6; + optional uint32 Checksum = 7; + optional string FilePath = 8; + optional int32 SMID = 9; + optional uint64 Offset = 10; + optional bytes Buffer = 11; +} + +message AcceptorStateData +{ + required uint64 InstanceID = 1; + required uint64 PromiseID = 2; + required uint64 PromiseNodeID = 3; + required uint64 AcceptedID = 4; + required uint64 AcceptedNodeID = 5; + required bytes AcceptedValue = 6; + required uint32 Checksum = 7; +}; + +message PaxosNodeInfo +{ + required uint64 Rid = 1; + required uint64 Nodeid = 2; +}; + +message SystemVariables +{ + required uint64 Gid = 1; + repeated PaxosNodeInfo MemberShip = 2; + required uint64 Version = 3; +}; + +message MasterVariables +{ + required uint64 MasterNodeid = 1; + required uint64 Version = 2; + required uint32 LeaseTime = 3; +}; diff --git a/src/communicate/Makefile.define b/src/communicate/Makefile.define new file mode 100644 index 000000000..a236d016f --- /dev/null +++ b/src/communicate/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libcommunicate.a + +COMMUNICATE_OBJ=dfnetwork.o udp.o network.o communicate.o + +COMMUNICATE_LIB=communicate src/utils:utils src/comm:comm src/config:config include:include src/communicate/tcp:communicate_tcp + +COMMUNICATE_SYS_LIB= + +COMMUNICATE_INCS=$(SRC_BASE_PATH)/src/communicate + +COMMUNICATE_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/communicate/communicate.cpp b/src/communicate/communicate.cpp new file mode 100644 index 000000000..44d7237e2 --- /dev/null +++ b/src/communicate/communicate.cpp @@ -0,0 +1,127 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "communicate.h" +#include "comm_include.h" +#include "commdef.h" + +namespace phxpaxos +{ + +Communicate :: Communicate( + const Config * poConfig, + const nodeid_t iMyNodeID, + const int iUDPMaxSize, + NetWork * poNetwork) + : m_poConfig((Config *)poConfig), m_poNetwork(poNetwork), m_iMyNodeID(iMyNodeID), m_iUDPMaxSize(iUDPMaxSize) +{ +} + +Communicate :: ~Communicate() +{ +} + +int Communicate :: Send(const nodeid_t iNodeID, const NodeInfo & oNodeInfo, + const std::string & sMessage, const int iSendType) +{ + if ((int)sMessage.size() > MAX_VALUE_SIZE) + { + BP->GetNetworkBP()->SendRejectByTooLargeSize(); + PLGErr("Message size too large %zu, max size %u, skip message", + sMessage.size(), MAX_VALUE_SIZE); + return 0; + } + + BP->GetNetworkBP()->Send(sMessage); + + if (sMessage.size() > m_iUDPMaxSize || iSendType == Message_SendType_TCP) + { + BP->GetNetworkBP()->SendTcp(sMessage); + return m_poNetwork->SendMessageTCP(oNodeInfo.GetIP(), oNodeInfo.GetPort(), sMessage); + } + else + { + BP->GetNetworkBP()->SendUdp(sMessage); + return m_poNetwork->SendMessageUDP(oNodeInfo.GetIP(), oNodeInfo.GetPort(), sMessage); + } +} + +int Communicate :: SendMessage(const nodeid_t iSendtoNodeID, const std::string & sMessage, const int iSendType) +{ + return Send(iSendtoNodeID, NodeInfo(iSendtoNodeID), sMessage, iSendType); +} + +int Communicate :: BroadcastMessage(const std::string & sMessage, const int iSendType) +{ + const std::set & setNodeInfo = m_poConfig->GetSystemVSM()->GetMembershipMap(); + + for (auto & it : setNodeInfo) + { + if (it != m_iMyNodeID) + { + Send(it, NodeInfo(it), sMessage, iSendType); + } + } + + return 0; +} + +int Communicate :: BroadcastMessageFollower(const std::string & sMessage, const int iSendType) +{ + const std::map & mapFollowerNodeInfo = m_poConfig->GetMyFollowerMap(); + + for (auto & it : mapFollowerNodeInfo) + { + if (it.first != m_iMyNodeID) + { + Send(it.first, NodeInfo(it.first), sMessage, iSendType); + } + } + + PLGDebug("%zu node", mapFollowerNodeInfo.size()); + + return 0; +} + +int Communicate :: BroadcastMessageTempNode(const std::string & sMessage, const int iSendType) +{ + const std::map & mapTempNode = m_poConfig->GetTmpNodeMap(); + + for (auto & it : mapTempNode) + { + if (it.first != m_iMyNodeID) + { + Send(it.first, NodeInfo(it.first), sMessage, iSendType); + } + } + + PLGDebug("%zu node", mapTempNode.size()); + + return 0; +} + +void Communicate :: SetUDPMaxSize(const size_t iUDPMaxSize) +{ + m_iUDPMaxSize = iUDPMaxSize; +} + +} + diff --git a/src/communicate/communicate.h b/src/communicate/communicate.h new file mode 100644 index 000000000..af16221e8 --- /dev/null +++ b/src/communicate/communicate.h @@ -0,0 +1,69 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/network.h" +#include "phxpaxos/options.h" +#include +#include "msg_transport.h" +#include "config_include.h" + +namespace phxpaxos +{ + +class Communicate : public MsgTransport +{ +public: + Communicate( + const Config * poConfig, + const nodeid_t iMyNodeID, + const int iUDPMaxSize, + NetWork * poNetwork); + ~Communicate(); + + int SendMessage(const nodeid_t iSendtoNodeID, const std::string & sMessage, + const int iSendType = Message_SendType_UDP); + + int BroadcastMessage(const std::string & sMessage, + const int iSendType = Message_SendType_UDP); + + int BroadcastMessageFollower(const std::string & sMessage, + const int iSendType = Message_SendType_UDP); + + int BroadcastMessageTempNode(const std::string & sMessage, + const int iSendType = Message_SendType_UDP); + +public: + void SetUDPMaxSize(const size_t iUDPMaxSize); + +private: + int Send(const nodeid_t iNodeID, const NodeInfo & tNodeInfo, const std::string & sMessage, const int iSendType); + +private: + Config * m_poConfig; + NetWork * m_poNetwork; + + nodeid_t m_iMyNodeID; + size_t m_iUDPMaxSize; +}; + +} diff --git a/src/communicate/dfnetwork.cpp b/src/communicate/dfnetwork.cpp new file mode 100644 index 000000000..feb4a89f2 --- /dev/null +++ b/src/communicate/dfnetwork.cpp @@ -0,0 +1,86 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "dfnetwork.h" +#include "udp.h" + +namespace phxpaxos +{ + +DFNetWork :: DFNetWork() : m_oUDPRecv(this), m_oTcpIOThread(this) +{ +} + +DFNetWork :: ~DFNetWork() +{ + PLHead("NetWork Deleted!"); +} + +void DFNetWork :: StopNetWork() +{ + m_oUDPRecv.Stop(); + m_oUDPSend.Stop(); + m_oTcpIOThread.Stop(); +} + +int DFNetWork :: Init(const std::string & sListenIp, const int iListenPort) +{ + int ret = m_oUDPSend.Init(); + if (ret != 0) + { + return ret; + } + + ret = m_oUDPRecv.Init(iListenPort); + if (ret != 0) + { + return ret; + } + + ret = m_oTcpIOThread.Init(sListenIp, iListenPort); + if (ret != 0) + { + PLErr("m_oTcpIOThread Init fail, ret %d", ret); + return ret; + } + + return 0; +} + +void DFNetWork :: RunNetWork() +{ + m_oUDPSend.start(); + m_oUDPRecv.start(); + m_oTcpIOThread.start(); +} + +int DFNetWork :: SendMessageTCP(const std::string & sIp, const int iPort, const std::string & sMessage) +{ + return m_oTcpIOThread.AddMessage(sIp, iPort, sMessage); +} + +int DFNetWork :: SendMessageUDP(const std::string & sIp, const int iPort, const std::string & sMessage) +{ + return m_oUDPSend.AddMessage(sIp, iPort, sMessage); +} + +} + diff --git a/src/communicate/dfnetwork.h b/src/communicate/dfnetwork.h new file mode 100644 index 000000000..041fd9c45 --- /dev/null +++ b/src/communicate/dfnetwork.h @@ -0,0 +1,54 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include "udp.h" +#include "tcp.h" +#include "phxpaxos/network.h" + +namespace phxpaxos +{ + +class DFNetWork : public NetWork +{ +public: + DFNetWork(); + virtual ~DFNetWork(); + + int Init(const std::string & sListenIp, const int iListenPort); + + void RunNetWork(); + + void StopNetWork(); + + int SendMessageTCP(const std::string & sIp, const int iPort, const std::string & sMessage); + + int SendMessageUDP(const std::string & sIp, const int iPort, const std::string & sMessage); + +private: + UDPRecv m_oUDPRecv; + UDPSend m_oUDPSend; + TcpIOThread m_oTcpIOThread; +}; + +} diff --git a/src/communicate/network.cpp b/src/communicate/network.cpp new file mode 100644 index 000000000..b9665de14 --- /dev/null +++ b/src/communicate/network.cpp @@ -0,0 +1,48 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "phxpaxos/network.h" +#include "phxpaxos/node.h" +#include "commdef.h" + +namespace phxpaxos +{ + +NetWork :: NetWork() : m_poNode(nullptr) +{ +} + +int NetWork :: OnReceiveMessage(const char * pcMessage, const int iMessageLen) +{ + if (m_poNode != nullptr) + { + m_poNode->OnReceiveMessage(pcMessage, iMessageLen); + } + else + { + PLHead("receive msglen %d", iMessageLen); + } + + return 0; +} + +} + diff --git a/src/communicate/tcp/Makefile.define b/src/communicate/tcp/Makefile.define new file mode 100644 index 000000000..05951f2c5 --- /dev/null +++ b/src/communicate/tcp/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libcommunicate_tcp.a + +COMMUNICATE_TCP_OBJ=event_base.o message_event.o event_loop.o tcp_client.o tcp_acceptor.o notify.o tcp.o + +COMMUNICATE_TCP_LIB=communicate_tcp src/utils:utils include:include src/comm:comm + +COMMUNICATE_TCP_SYS_LIB= + +COMMUNICATE_TCP_INCS=$(SRC_BASE_PATH)/src/communicate/tcp + +COMMUNICATE_TCP_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/communicate/tcp/event_base.cpp b/src/communicate/tcp/event_base.cpp new file mode 100644 index 000000000..87a5fd210 --- /dev/null +++ b/src/communicate/tcp/event_base.cpp @@ -0,0 +1,112 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "event_base.h" +#include "event_loop.h" + +namespace phxpaxos +{ + +Event :: Event(EventLoop * poEventLoop) : + m_iEvents(0), m_poEventLoop(poEventLoop) +{ + m_bIsDestroy = false; +} + +Event :: ~Event() +{ +} + +int Event :: OnRead() +{ + PLErr("Need Impl"); + return -1; +} + +int Event :: OnWrite() +{ + PLErr("Need Impl"); + return -1; +} + +void Event :: OnTimeout(const uint32_t iTimerID, const int iType) +{ + PLErr("Need Impl"); +} + +void Event :: JumpoutEpollWait() +{ + m_poEventLoop->JumpoutEpollWait(); +} + +void Event :: AddEvent(const int iEvents) +{ + int iBeforeEvent = m_iEvents; + m_iEvents |= iEvents; + if (m_iEvents == iBeforeEvent) + { + return; + } + + m_poEventLoop->ModEvent(this, m_iEvents); +} + +void Event :: RemoveEvent(const int iEvents) +{ + int iBeforeEvent = m_iEvents; + m_iEvents &= (~iEvents); + if (m_iEvents == iBeforeEvent) + { + return; + } + + if (m_iEvents == 0) + { + m_poEventLoop->RemoveEvent(this); + } + else + { + m_poEventLoop->ModEvent(this, m_iEvents); + } +} + +void Event :: AddTimer(const int iTimeoutMs, const int iType, uint32_t & iTimerID) +{ + m_poEventLoop->AddTimer(this, iTimeoutMs, iType, iTimerID); +} + +void Event :: RemoveTimer(const uint32_t iTimerID) +{ + m_poEventLoop->RemoveTimer(iTimerID); +} + +void Event :: Destroy() +{ + m_bIsDestroy = true; +} + +const bool Event :: IsDestroy() const +{ + return m_bIsDestroy; +} + +} + diff --git a/src/communicate/tcp/event_base.h b/src/communicate/tcp/event_base.h new file mode 100644 index 000000000..055836741 --- /dev/null +++ b/src/communicate/tcp/event_base.h @@ -0,0 +1,72 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "commdef.h" + +namespace phxpaxos +{ + +class EventLoop; + +class Event +{ +public: + Event(EventLoop * poEventLoop); + virtual ~Event(); + + virtual int GetSocketFd() const = 0; + + virtual const std::string & GetSocketHost() = 0; + + virtual int OnRead(); + + virtual int OnWrite(); + + virtual void OnError(bool & bNeedDelete) = 0; + + virtual void OnTimeout(const uint32_t iTimerID, const int iType); + +public: + void AddEvent(const int iEvents); + + void RemoveEvent(const int iEvents); + + void JumpoutEpollWait(); + + const bool IsDestroy() const; + + void Destroy(); + +public: + void AddTimer(const int iTimeoutMs, const int iType, uint32_t & iTimerID); + + void RemoveTimer(const uint32_t iTimerID); + +protected: + int m_iEvents; + EventLoop * m_poEventLoop; + + bool m_bIsDestroy; +}; + +} diff --git a/src/communicate/tcp/event_loop.cpp b/src/communicate/tcp/event_loop.cpp new file mode 100644 index 000000000..9c339097e --- /dev/null +++ b/src/communicate/tcp/event_loop.cpp @@ -0,0 +1,335 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "event_loop.h" +#include "event_base.h" +#include "tcp_acceptor.h" +#include "tcp_client.h" +#include "comm_include.h" + +using namespace std; + +namespace phxpaxos +{ + +EventLoop :: EventLoop() +{ + m_iEpollFd = -1; + m_bIsEnd = false; + m_poTcpAcceptor = nullptr; + m_poTcpClient = nullptr; + m_poNotify = nullptr; +} + +EventLoop :: ~EventLoop() +{ +} + +void EventLoop :: JumpoutEpollWait() +{ + m_poNotify->SendNotify(); +} + +void EventLoop :: SetTcpAcceptor(TcpAcceptor * poTcpAcceptor) +{ + m_poTcpAcceptor = poTcpAcceptor; +} + +void EventLoop :: SetTcpClient(TcpClient * poTcpClient) +{ + m_poTcpClient = poTcpClient; +} + +int EventLoop :: Init(const int iEpollLength) +{ + m_iEpollFd = epoll_create(iEpollLength); + if (m_iEpollFd == -1) + { + PLErr("epoll_create fail, ret %d", m_iEpollFd); + return -1; + } + + m_poNotify = new Notify(this); + assert(m_poNotify != nullptr); + + int ret = m_poNotify->Init(); + if (ret != 0) + { + return ret; + } + + return 0; +} + +void EventLoop :: ModEvent(const Event * poEvent, const int iEvents) +{ + auto it = m_mapEvent.find(poEvent->GetSocketFd()); + int iEpollOpertion = 0; + if (it == end(m_mapEvent)) + { + iEpollOpertion = EPOLL_CTL_ADD; + } + else + { + iEpollOpertion = it->second.m_iEvents ? EPOLL_CTL_MOD : EPOLL_CTL_ADD; + } + + epoll_event tEpollEvent; + tEpollEvent.events = iEvents; + tEpollEvent.data.fd = poEvent->GetSocketFd(); + + int ret = epoll_ctl(m_iEpollFd, iEpollOpertion, poEvent->GetSocketFd(), &tEpollEvent); + if (ret == -1) + { + PLErr("epoll_ctl fail, EpollFd %d EpollOpertion %d SocketFd %d EpollEvent %d", + m_iEpollFd, iEpollOpertion, poEvent->GetSocketFd(), iEvents); + + //to do + return; + } + + EventCtx tCtx; + tCtx.m_poEvent = (Event *)poEvent; + tCtx.m_iEvents = iEvents; + + m_mapEvent[poEvent->GetSocketFd()] = tCtx; +} + +void EventLoop :: RemoveEvent(const Event * poEvent) +{ + auto it = m_mapEvent.find(poEvent->GetSocketFd()); + if (it == end(m_mapEvent)) + { + return; + } + + int iEpollOpertion = EPOLL_CTL_DEL; + + epoll_event tEpollEvent; + tEpollEvent.events = 0; + tEpollEvent.data.fd = poEvent->GetSocketFd(); + + int ret = epoll_ctl(m_iEpollFd, iEpollOpertion, poEvent->GetSocketFd(), &tEpollEvent); + if (ret == -1) + { + PLErr("epoll_ctl fail, EpollFd %d EpollOpertion %d SocketFd %d", + m_iEpollFd, iEpollOpertion, poEvent->GetSocketFd()); + + //to do + //when error + return; + } + + m_mapEvent.erase(poEvent->GetSocketFd()); +} + +void EventLoop :: StartLoop() +{ + m_bIsEnd = false; + while(true) + { + BP->GetNetworkBP()->TcpEpollLoop(); + + int iNextTimeout = 1000; + + DealwithTimeout(iNextTimeout); + + //PLHead("nexttimeout %d", iNextTimeout); + + OneLoop(iNextTimeout); + + //deal with accept fds + if (m_poTcpAcceptor != nullptr) + { + m_poTcpAcceptor->CreateEvent(); + } + + if (m_poTcpClient != nullptr) + { + m_poTcpClient->DealWithWrite(); + } + + if (m_bIsEnd) + { + PLHead("TCP.EventLoop [END]"); + break; + } + } +} + +void EventLoop :: Stop() +{ + m_bIsEnd = true; +} + +void EventLoop :: OneLoop(const int iTimeoutMs) +{ + int n = epoll_wait(m_iEpollFd, m_EpollEvents, MAX_EVENTS, 1); + if (n == -1) + { + if (errno != EINTR) + { + PLErr("epoll_wait fail, errno %d", errno); + return; + } + } + + for (int i = 0; i < n; i++) + { + int iFd = m_EpollEvents[i].data.fd; + auto it = m_mapEvent.find(iFd); + if (it == end(m_mapEvent)) + { + continue; + } + + int iEvents = m_EpollEvents[i].events; + Event * poEvent = it->second.m_poEvent; + + int ret = 0; + if (iEvents & EPOLLERR) + { + OnError(iEvents, poEvent); + continue; + } + + try + { + if (iEvents & EPOLLIN) + { + ret = poEvent->OnRead(); + } + + if (iEvents & EPOLLOUT) + { + ret = poEvent->OnWrite(); + } + } + catch (...) + { + ret = -1; + } + + if (ret != 0) + { + OnError(iEvents, poEvent); + } + } +} + +void EventLoop :: OnError(const int iEvents, Event * poEvent) +{ + BP->GetNetworkBP()->TcpOnError(); + + PLErr("event error, events %d socketfd %d socket ip %s errno %d", + iEvents, poEvent->GetSocketFd(), poEvent->GetSocketHost().c_str(), errno); + + RemoveEvent(poEvent); + + bool bNeedDelete = false; + poEvent->OnError(bNeedDelete); + + if (bNeedDelete) + { + poEvent->Destroy(); + } +} + +bool EventLoop :: AddTimer(const Event * poEvent, const int iTimeout, const int iType, uint32_t & iTimerID) +{ + if (poEvent->GetSocketFd() == 0) + { + return false; + } + + if (m_mapEvent.find(poEvent->GetSocketFd()) == end(m_mapEvent)) + { + EventCtx tCtx; + tCtx.m_poEvent = (Event *)poEvent; + tCtx.m_iEvents = 0; + + m_mapEvent[poEvent->GetSocketFd()] = tCtx; + } + + uint64_t llAbsTime = Time::GetTimestampMS() + iTimeout; + m_oTimer.AddTimerWithType(llAbsTime, iType, iTimerID); + + m_mapTimerID2FD[iTimerID] = poEvent->GetSocketFd(); + + return true; +} + +void EventLoop :: RemoveTimer(const uint32_t iTimerID) +{ + auto it = m_mapTimerID2FD.find(iTimerID); + if (it != end(m_mapTimerID2FD)) + { + m_mapTimerID2FD.erase(it); + } +} + +void EventLoop :: DealwithTimeoutOne(const uint32_t iTimerID, const int iType) +{ + auto it = m_mapTimerID2FD.find(iTimerID); + if (it == end(m_mapTimerID2FD)) + { + //PLErr("Timeout aready remove!, timerid %u iType %d", iTimerID, iType); + return; + } + + int iSocketFd = it->second; + + m_mapTimerID2FD.erase(it); + + auto eventIt = m_mapEvent.find(iSocketFd); + if (eventIt == end(m_mapEvent)) + { + return; + } + + eventIt->second.m_poEvent->OnTimeout(iTimerID, iType); +} + +void EventLoop :: DealwithTimeout(int & iNextTimeout) +{ + bool bHasTimeout = true; + + while(bHasTimeout) + { + uint32_t iTimerID = 0; + int iType = 0; + bHasTimeout = m_oTimer.PopTimeout(iTimerID, iType); + + if (bHasTimeout) + { + DealwithTimeoutOne(iTimerID, iType); + + iNextTimeout = m_oTimer.GetNextTimeout(); + if (iNextTimeout != 0) + { + break; + } + } + } +} + +} + diff --git a/src/communicate/tcp/event_loop.h b/src/communicate/tcp/event_loop.h new file mode 100644 index 000000000..0c7166091 --- /dev/null +++ b/src/communicate/tcp/event_loop.h @@ -0,0 +1,97 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include "timer.h" +#include "notify.h" + +namespace phxpaxos +{ + +#define MAX_EVENTS 1024 + +class Event; +class TcpAcceptor; +class TcpClient; + +class EventLoop +{ +public: + EventLoop(); + virtual ~EventLoop(); + + int Init(const int iEpollLength); + + void ModEvent(const Event * poEvent, const int iEvents); + + void RemoveEvent(const Event * poEvent); + + void StartLoop(); + + void Stop(); + + void OnError(const int iEvents, Event * poEvent); + + virtual void OneLoop(const int iTimeoutMs); + +public: + void SetTcpAcceptor(TcpAcceptor * poTcpAcceptor); + + void SetTcpClient(TcpClient * poTcpClient); + + void JumpoutEpollWait(); + +public: + bool AddTimer(const Event * poEvent, const int iTimeout, const int iType, uint32_t & iTimerID); + + void RemoveTimer(const uint32_t iTimerID); + + void DealwithTimeout(int & iNextTimeout); + + void DealwithTimeoutOne(const uint32_t iTimerID, const int iType); + +public: + typedef struct EventCtx + { + Event * m_poEvent; + int m_iEvents; + } EventCtx_t; + +private: + bool m_bIsEnd; + +protected: + int m_iEpollFd; + epoll_event m_EpollEvents[MAX_EVENTS]; + std::map m_mapEvent; + TcpAcceptor * m_poTcpAcceptor; + TcpClient * m_poTcpClient; + Notify * m_poNotify; + +protected: + Timer m_oTimer; + std::map m_mapTimerID2FD; +}; + +} diff --git a/src/communicate/tcp/message_event.cpp b/src/communicate/tcp/message_event.cpp new file mode 100644 index 000000000..396ab4663 --- /dev/null +++ b/src/communicate/tcp/message_event.cpp @@ -0,0 +1,462 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "message_event.h" +#include "commdef.h" +#include "phxpaxos/network.h" +#include "event_loop.h" +#include "comm_include.h" + +namespace phxpaxos +{ + +MessageEvent :: MessageEvent( + const int iType, + const int fd, + const SocketAddress & oAddr, + EventLoop * poEventLoop, + NetWork * poNetWork) : + Event(poEventLoop), m_oSocket(fd), m_oAddr(oAddr), m_poNetWork(poNetWork) +{ + m_iType = iType; + + m_iLeftReadLen = 0; + m_iLastReadPos = 0; + + m_iLeftWriteLen = 0; + m_iLastWritePos = 0; + + memset(m_sReadHeadBuffer, 0, sizeof(m_sReadHeadBuffer)); + m_iLastReadHeadPos = 0; + + m_oSocket.setNonBlocking(true); + m_oSocket.setNoDelay(true); + + m_iReconnectTimeoutID = 0; + + m_llLastActiveTime = Time::GetTimestampMS(); + m_sHost = oAddr.getHost(); + + m_iQueueMemSize = 0; +} + +MessageEvent :: ~MessageEvent() +{ + while (!m_oInQueue.empty()) + { + QueueData tData = m_oInQueue.front(); + m_oInQueue.pop(); + + delete tData.psValue; + } +} + +int MessageEvent :: GetSocketFd() const +{ + return m_oSocket.getSocketHandle(); +} + +const std::string & MessageEvent :: GetSocketHost() +{ + return m_sHost; +} + +const bool MessageEvent :: IsActive() +{ + uint64_t llNowTime = Time::GetTimestampMS(); + if (llNowTime > m_llLastActiveTime + && ((int)(llNowTime - m_llLastActiveTime) > CONNECTTION_NONACTIVE_TIMEOUT)) + { + return false; + } + + return true; +} + +int MessageEvent :: AddMessage(const std::string & sMessage) +{ + m_llLastActiveTime = Time::GetTimestampMS(); + + m_oMutex.lock(); + + if ((int)m_oInQueue.size() > TCP_QUEUE_MAXLEN) + { + BP->GetNetworkBP()->TcpQueueFull(); + m_oMutex.unlock(); + + PLErr("queue length %d too long, can't enqueue", m_oInQueue.size()); + return -2; + } + + if (m_iQueueMemSize > MAX_QUEUE_MEM_SIZE) + { + m_oMutex.unlock(); + PLErr("queue memsize %d too large, can't enqueue", m_iQueueMemSize); + return -2; + } + + QueueData tData; + tData.llEnqueueAbsTime = Time::GetTimestampMS(); + tData.psValue = new string(sMessage); + m_oInQueue.push(tData); + + m_iQueueMemSize += sMessage.size(); + + m_oMutex.unlock(); + + JumpoutEpollWait(); + + return 0; +} + +void MessageEvent :: ReadDone(BytesBuffer & oBytesBuffer, const int iLen) +{ + //PLHead("ok, len %d", iLen); + m_poNetWork->OnReceiveMessage(oBytesBuffer.GetPtr(), iLen); + + BP->GetNetworkBP()->TcpReadOneMessageOk(iLen); +} + +int MessageEvent :: ReadLeft() +{ + bool bAgain = false; + int iReadLen = m_oSocket.receive(m_oReadCacheBuffer.GetPtr() + m_iLastReadPos, m_iLeftReadLen, &bAgain); + //PLImp("readlen %d", iReadLen); + if (iReadLen == 0) + { + //socket broken + return -1; + } + + m_iLeftReadLen -= iReadLen; + m_iLastReadPos += iReadLen; + + if (m_iLeftReadLen == 0) + { + ReadDone(m_oReadCacheBuffer, m_iLastReadPos); + m_iLeftReadLen = 0; + m_iLastReadPos = 0; + } + + return 0; +} + +int MessageEvent :: OnRead() +{ + if (m_iLeftReadLen > 0) + { + return ReadLeft(); + } + + int iReadLen = m_oSocket.receive(m_sReadHeadBuffer + m_iLastReadHeadPos, sizeof(int) - m_iLastReadHeadPos); + if (iReadLen == 0) + { + BP->GetNetworkBP()->TcpOnReadMessageLenError(); + PLErr("read head fail, readlen %d, socket broken", iReadLen); + return -1; + } + + m_iLastReadHeadPos += iReadLen; + if (m_iLastReadHeadPos < (int)sizeof(int)) + { + PLImp("head read pos %d small than sizeof(int) %zu", m_iLastReadHeadPos, sizeof(int)); + return 0; + } + + m_iLastReadHeadPos = 0; + int niLen = 0; + int iLen = 0; + memcpy((char *)&niLen, m_sReadHeadBuffer, sizeof(int)); + iLen = ntohl(niLen) - 4; + + if (iLen < 0 || iLen > MAX_VALUE_SIZE) + { + PLErr("need to read len wrong %d", iLen); + return -2; + } + + m_oReadCacheBuffer.Ready(iLen); + + m_iLeftReadLen = iLen; + m_iLastReadPos = 0; + + //second read maybe no data read, so readlen == 0 is ok. + bool bAgain = false; + iReadLen = m_oSocket.receive(m_oReadCacheBuffer.GetPtr(), iLen, &bAgain); + if (iReadLen == 0) + { + if (!bAgain) + { + PLErr("second read data fail, readlen %d, no again, socket broken", iReadLen); + return -1; + } + else + { + PLErr("second read data, readlen %d need again", iReadLen); + return 0; + } + } + + if (iReadLen == iLen) + { + ReadDone(m_oReadCacheBuffer, iLen); + m_iLeftReadLen = 0; + m_iLastReadPos = 0; + } + else if (iReadLen < iLen) + { + m_iLastReadPos = iReadLen; + m_iLeftReadLen = iLen - iReadLen; + + PLImp("read buflen %d small than except len %d", iReadLen, iLen); + } + else + { + PLErr("read buflen %d large than except len %d", iReadLen, iLen); + return -2; + } + + return 0; +} + +void MessageEvent :: OpenWrite() +{ + if (!m_oInQueue.empty()) + { + if (IsDestroy()) + { + PLErr("this connection fd:%d host:%s is destroy, reconnect", GetSocketFd(), GetSocketHost().c_str()); + ReConnect(); + m_bIsDestroy = false; + } + else + { + AddEvent(EPOLLOUT); + } + } +} + +void MessageEvent :: WriteDone() +{ + //PLHead("ok"); + RemoveEvent(EPOLLOUT); +} + +int MessageEvent :: WriteLeft() +{ + int iWriteLen = m_oSocket.send(m_oWriteCacheBuffer.GetPtr() + m_iLastWritePos, m_iLeftWriteLen); + //PLImp("writelen %d", iWriteLen); + if (iWriteLen < 0) + { + return -1; + } + + if (iWriteLen == 0) + { + //no buffer to write, wait next epoll_wait + //need wait next write + AddEvent(EPOLLOUT); + + return 1; + } + + m_iLeftWriteLen -= iWriteLen; + m_iLastWritePos += iWriteLen; + + if (m_iLeftWriteLen == 0) + { + m_iLeftWriteLen = 0; + m_iLastWritePos = 0; + } + + return 0; +} + +int MessageEvent :: OnWrite() +{ + int ret = 0; + while (!m_oInQueue.empty() || m_iLeftWriteLen > 0) + { + ret = DoOnWrite(); + if (ret != 0 && ret != 1) + { + return ret; + } + else if (ret == 1) + { + //need break, wait next write + return 0; + } + } + + WriteDone(); + + return 0; +} + +int MessageEvent :: DoOnWrite() +{ + if (m_iLeftWriteLen > 0) + { + return WriteLeft(); + } + + m_oMutex.lock(); + QueueData tData = m_oInQueue.front(); + m_oInQueue.pop(); + m_iQueueMemSize -= tData.psValue->size(); + m_oMutex.unlock(); + + std::string * poMessage = tData.psValue; + uint64_t llNowTime = Time::GetTimestampMS(); + if (llNowTime > tData.llEnqueueAbsTime + && (((int)(llNowTime - tData.llEnqueueAbsTime)) > TCP_OUTQUEUE_DROP_TIMEMS)) + { + PLErr("drop request because enqueue timeout, enqueuetime %lu nowtime %lu", + llNowTime, tData.llEnqueueAbsTime); + delete poMessage; + return 0; + } + + int iBuffLen = poMessage->size(); + int niBuffLen = htonl(iBuffLen + 4); + + int iLen = iBuffLen + 4; + m_oWriteCacheBuffer.Ready(iLen); + memcpy(m_oWriteCacheBuffer.GetPtr(), &niBuffLen, 4); + memcpy(m_oWriteCacheBuffer.GetPtr() + 4, poMessage->c_str(), iBuffLen); + + m_iLeftWriteLen = iLen; + m_iLastWritePos = 0; + + delete poMessage; + + //PLImp("write len %d ip %s port %d", iLen, m_oAddr.getHost().c_str(), m_oAddr.getPort()); + + int iWriteLen = m_oSocket.send(m_oWriteCacheBuffer.GetPtr(), iLen); + if (iWriteLen < 0) + { + PLErr("fail, write len %d ip %s port %d", + iWriteLen, m_oAddr.getHost().c_str(), m_oAddr.getPort()); + return -1; + } + + if (iWriteLen == 0) + { + //need wait next write + AddEvent(EPOLLOUT); + + return 1; + } + + //PLImp("real write len %d", iWriteLen); + + if (iWriteLen == iLen) + { + m_iLeftWriteLen = 0; + m_iLastWritePos = 0; + //write done + } + else if (iWriteLen < iLen) + { + m_iLastWritePos = iWriteLen; + m_iLeftWriteLen = iLen - iWriteLen; + + PLImp("write buflen %d smaller than expectlen %d", iWriteLen, iLen); + } + else + { + PLErr("write buflen %d large than expectlen %d", iWriteLen, iLen); + } + + return 0; +} + +void MessageEvent :: OnError(bool & bNeedDelete) +{ + bNeedDelete = false; + + if (m_iType == MessageEventType_RECV) + { + bNeedDelete = true; + return; + } + else if (m_iType == MessageEventType_SEND) + { + if (IsActive()) + { + AddTimer(200, MessageEventTimerType_Reconnect, m_iReconnectTimeoutID); + } + else + { + PLErr("this connection %s not active, delete it.", GetSocketHost().c_str()); + + m_oMutex.lock(); + + while (!m_oInQueue.empty()) + { + QueueData tData = m_oInQueue.front(); + m_oInQueue.pop(); + + delete tData.psValue; + } + + m_iQueueMemSize = 0; + + m_oMutex.unlock(); + + bNeedDelete = true; + return; + } + } +} + +void MessageEvent :: OnTimeout(const uint32_t iTimerID, const int iType) +{ + if (iTimerID != m_iReconnectTimeoutID) + { + return; + } + + if (iType == MessageEventTimerType_Reconnect) + { + ReConnect(); + } +} + +void MessageEvent :: ReConnect() +{ + BP->GetNetworkBP()->TcpReconnect(); + + //reset event + m_iEvents = 0; + + m_oSocket.reset(); + m_oSocket.setNonBlocking(true); + m_oSocket.setNoDelay(true); + m_oSocket.connect(m_oAddr); + AddEvent(EPOLLOUT); + + PLErr("start, ip %s", GetSocketHost().c_str()); +} + +} + diff --git a/src/communicate/tcp/message_event.h b/src/communicate/tcp/message_event.h new file mode 100644 index 000000000..e3b6d2ddc --- /dev/null +++ b/src/communicate/tcp/message_event.h @@ -0,0 +1,122 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "event_base.h" +#include "utils_include.h" +#include "commdef.h" +#include "comm_include.h" + +namespace phxpaxos +{ + +class EventLoop; +class NetWork; + +enum MessageEventType +{ + MessageEventType_RECV = 1, + MessageEventType_SEND = 2, +}; + +enum MessageEventTimerType +{ + MessageEventTimerType_Reconnect = 1, +}; + +class MessageEvent : public Event +{ +public: + MessageEvent( + const int Type, + const int fd, + const SocketAddress & oAddr, + EventLoop * poEventLoop, + NetWork * poNetWork); + ~MessageEvent(); + + int AddMessage(const std::string & sMessage); + + int GetSocketFd() const; + + const std::string & GetSocketHost(); + + int OnRead(); + + int OnWrite(); + + void OnTimeout(const uint32_t iTimerID, const int iType); + + void OnError(bool & bNeedDelete); + + void OpenWrite(); + + const bool IsActive(); + +private: + int ReadLeft(); + + void ReadDone(BytesBuffer & oBytesBuffer, const int iLen); + + int WriteLeft(); + + void WriteDone(); + + int DoOnWrite(); + + void ReConnect(); + +private: + Socket m_oSocket; + SocketAddress m_oAddr; + std::string m_sHost; + NetWork * m_poNetWork; + int m_iType; + +private: + char m_sReadHeadBuffer[sizeof(int)]; + int m_iLastReadHeadPos; + BytesBuffer m_oReadCacheBuffer; + int m_iLastReadPos; + int m_iLeftReadLen; + + BytesBuffer m_oWriteCacheBuffer; + int m_iLastWritePos; + int m_iLeftWriteLen; + + struct QueueData + { + uint64_t llEnqueueAbsTime; + std::string * psValue; + }; + + std::queue m_oInQueue; + int m_iQueueMemSize; + Mutex m_oMutex; + + uint64_t m_llLastActiveTime; + +private: + uint32_t m_iReconnectTimeoutID; +}; + +} diff --git a/src/communicate/tcp/notify.cpp b/src/communicate/tcp/notify.cpp new file mode 100644 index 000000000..5847a48ff --- /dev/null +++ b/src/communicate/tcp/notify.cpp @@ -0,0 +1,91 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "notify.h" +#include "commdef.h" +#include +#include +#include + +namespace phxpaxos +{ + +Notify :: Notify(EventLoop * poEventLoop) + : Event(poEventLoop) +{ + m_iPipeFD[0] = -1; + m_iPipeFD[1] = -1; + m_sHost = "Notify"; +} + +Notify :: ~Notify() +{ + for (int i = 0; i < 2; i++) + { + if (m_iPipeFD[i] != -1) + { + close(m_iPipeFD[i]); + } + } +} + +int Notify :: Init() +{ + int ret = pipe(m_iPipeFD); + if (ret != 0) + { + PLErr("create pipe fail, ret %d", ret); + return ret; + } + + AddEvent(EPOLLIN); + return 0; +} + +int Notify :: GetSocketFd() const +{ + return m_iPipeFD[0]; +} + +const std::string & Notify :: GetSocketHost() +{ + return m_sHost; +} + +void Notify :: SendNotify() +{ + write(m_iPipeFD[1], (void *)"a", 1); +} + +int Notify :: OnRead() +{ + char sTmp[2] = {0}; + read(m_iPipeFD[0], sTmp, 1); + return 0; +} + +void Notify :: OnError(bool & bNeedDelete) +{ + bNeedDelete = false; +} + +} + diff --git a/src/communicate/tcp/notify.h b/src/communicate/tcp/notify.h new file mode 100644 index 000000000..f8a24c549 --- /dev/null +++ b/src/communicate/tcp/notify.h @@ -0,0 +1,55 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "event_base.h" +#include + +namespace phxpaxos +{ + +class EventLoop; + +class Notify : public Event +{ +public: + Notify(EventLoop * poEventLoop); + ~Notify(); + + int Init(); + + int GetSocketFd() const; + + const std::string & GetSocketHost(); + + void SendNotify(); + + int OnRead(); + + void OnError(bool & bNeedDelete); + +private: + int m_iPipeFD[2]; + std::string m_sHost; +}; + +} diff --git a/src/communicate/tcp/tcp.cpp b/src/communicate/tcp/tcp.cpp new file mode 100644 index 000000000..72aa41d81 --- /dev/null +++ b/src/communicate/tcp/tcp.cpp @@ -0,0 +1,72 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "tcp.h" +#include "phxpaxos/network.h" + +namespace phxpaxos +{ + +TcpIOThread :: TcpIOThread(NetWork * poNetWork) + : m_oTcpAcceptor(&m_oEventLoop, poNetWork), + m_oTcpClient(&m_oEventLoop, poNetWork) +{ + m_oEventLoop.SetTcpAcceptor(&m_oTcpAcceptor); + m_oEventLoop.SetTcpClient(&m_oTcpClient); + + assert(signal(SIGPIPE, SIG_IGN) != SIG_ERR); + assert(signal(SIGALRM, SIG_IGN) != SIG_ERR); + assert(signal(SIGCHLD, SIG_IGN) != SIG_ERR); +} + +TcpIOThread :: ~TcpIOThread() +{ +} + +void TcpIOThread :: Stop() +{ + m_oTcpAcceptor.Stop(); + m_oEventLoop.Stop(); + + join(); + + PLHead("TcpIOThread [END]"); +} + +int TcpIOThread :: Init(const std::string & sListenIp, const int iListenPort) +{ + m_oTcpAcceptor.Listen(sListenIp, iListenPort); + return m_oEventLoop.Init(20480); +} + +void TcpIOThread :: run() +{ + m_oTcpAcceptor.start(); + m_oEventLoop.StartLoop(); +} + +int TcpIOThread :: AddMessage(const std::string & sIP, const int iPort, const std::string & sMessage) +{ + return m_oTcpClient.AddMessage(sIP, iPort, sMessage); +} + +} + diff --git a/src/communicate/tcp/tcp.h b/src/communicate/tcp/tcp.h new file mode 100644 index 000000000..214d7a7a1 --- /dev/null +++ b/src/communicate/tcp/tcp.h @@ -0,0 +1,52 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "event_loop.h" +#include "tcp_acceptor.h" +#include "tcp_client.h" +#include "utils_include.h" + +namespace phxpaxos +{ + +class TcpIOThread : public Thread +{ +public: + TcpIOThread(NetWork * poNetWork); + ~TcpIOThread(); + + int Init(const std::string & sListenIp, const int iListenPort); + + void run(); + + void Stop(); + + int AddMessage(const std::string & sIP, const int iPort, const std::string & sMessage); + +private: + TcpAcceptor m_oTcpAcceptor; + TcpClient m_oTcpClient; + EventLoop m_oEventLoop; +}; + +} diff --git a/src/communicate/tcp/tcp_acceptor.cpp b/src/communicate/tcp/tcp_acceptor.cpp new file mode 100644 index 000000000..689822014 --- /dev/null +++ b/src/communicate/tcp/tcp_acceptor.cpp @@ -0,0 +1,167 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "tcp_acceptor.h" +#include "commdef.h" +#include "event_loop.h" +#include "phxpaxos/network.h" +#include "message_event.h" +#include "comm_include.h" +#include + +namespace phxpaxos +{ + +TcpAcceptor :: TcpAcceptor( + EventLoop * poEventLoop, + NetWork * poNetWork) + : m_poEventLoop(poEventLoop), + m_poNetWork(poNetWork) +{ + m_bIsEnd = false; +} + +TcpAcceptor :: ~TcpAcceptor() +{ + while (!m_oFDQueue.empty()) + { + AcceptData * poData = m_oFDQueue.front(); + m_oFDQueue.pop(); + + delete poData; + } + + ClearEvent(); +} + +void TcpAcceptor :: Listen(const std::string & sListenIP, const int iListenPort) +{ + m_oSocket.listen(SocketAddress(sListenIP, (unsigned short)iListenPort)); +} + +void TcpAcceptor :: Stop() +{ + m_bIsEnd = true; + join(); +} + +void TcpAcceptor :: run() +{ + PLHead("start accept..."); + + m_oSocket.setAcceptTimeout(500); + m_oSocket.setNonBlocking(true); + + while (true) + { + struct pollfd pfd; + int ret; + + pfd.fd = m_oSocket.getSocketHandle(); + pfd.events = POLLIN; + ret = poll(&pfd, 1, 500); + + if (ret != 0 && ret != -1) + { + SocketAddress oAddr; + int fd = -1; + try + { + fd = m_oSocket.acceptfd(&oAddr); + } + catch(...) + { + fd = -1; + } + + if (fd >= 0) + { + BP->GetNetworkBP()->TcpAcceptFd(); + + PLImp("accepted!, fd %d ip %s port %d", + fd, oAddr.getHost().c_str(), oAddr.getPort()); + AcceptData * poData = new AcceptData; + poData->fd = fd; + poData->oAddr = oAddr; + + m_oMutex.lock(); + m_oFDQueue.push(poData); + m_oMutex.unlock(); + } + } + + ClearEvent(); + + if (m_bIsEnd) + { + PLHead("TCP.Acceptor [END]"); + return; + } + } +} + +void TcpAcceptor :: CreateEvent() +{ + if (m_oFDQueue.empty()) + { + return; + } + + m_oMutex.lock(); + int iCreatePerTime = 200; + while ((!m_oFDQueue.empty()) && iCreatePerTime--) + { + AcceptData * poData = m_oFDQueue.front(); + m_oFDQueue.pop(); + + //create event for this fd + MessageEvent * poMessageEvent = new MessageEvent(MessageEventType_RECV, poData->fd, + poData->oAddr, m_poEventLoop, m_poNetWork); + poMessageEvent->AddEvent(EPOLLIN); + + m_vecCreatedEvent.push_back(poMessageEvent); + + delete poData; + } + + m_oMutex.unlock(); +} + +void TcpAcceptor :: ClearEvent() +{ + m_oMutex.lock(); + for (auto it = m_vecCreatedEvent.begin(); it != end(m_vecCreatedEvent);) + { + if ((*it)->IsDestroy()) + { + delete (*it); + it = m_vecCreatedEvent.erase(it); + } + else + { + it++; + } + } + m_oMutex.unlock(); +} + +} + diff --git a/src/communicate/tcp/tcp_acceptor.h b/src/communicate/tcp/tcp_acceptor.h new file mode 100644 index 000000000..0e1ed51fc --- /dev/null +++ b/src/communicate/tcp/tcp_acceptor.h @@ -0,0 +1,70 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "utils_include.h" +#include "message_event.h" + +namespace phxpaxos +{ + +class EventLoop; +class NetWork; + +class TcpAcceptor : public Thread +{ +public: + TcpAcceptor( + EventLoop * poEventLoop, + NetWork * poNetWork); + ~TcpAcceptor(); + + void Listen(const std::string & sListenIP, const int iListenPort); + + void run(); + + void Stop(); + + void CreateEvent(); + + void ClearEvent(); + +private: + ServerSocket m_oSocket; + EventLoop * m_poEventLoop; + NetWork * m_poNetWork; + +private: + struct AcceptData + { + int fd; + SocketAddress oAddr; + }; + std::queue m_oFDQueue; + Mutex m_oMutex; + + std::vector m_vecCreatedEvent; + + bool m_bIsEnd; +}; + +} diff --git a/src/communicate/tcp/tcp_client.cpp b/src/communicate/tcp/tcp_client.cpp new file mode 100644 index 000000000..6d55904db --- /dev/null +++ b/src/communicate/tcp/tcp_client.cpp @@ -0,0 +1,106 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "tcp_client.h" +#include "commdef.h" +#include "phxpaxos/network.h" +#include "event_loop.h" + +namespace phxpaxos +{ + +TcpClient :: TcpClient(EventLoop * poEventLoop, NetWork * poNetWork) + : m_poEventLoop(poEventLoop), m_poNetWork(poNetWork) +{ +} + +TcpClient :: ~TcpClient() +{ + for (auto & it : m_mapEvent) + { + delete it.second; + } +} + +int TcpClient :: AddMessage(const std::string & sIP, const int iPort, const std::string & sMessage) +{ + //PLImp("ok"); + MessageEvent * poEvent = GetEvent(sIP, iPort); + if (poEvent == nullptr) + { + PLErr("no event created for this ip %s port %d", sIP.c_str(), iPort); + return -1; + } + + return poEvent->AddMessage(sMessage); +} + +MessageEvent * TcpClient :: GetEvent(const std::string & sIP, const int iPort) +{ + uint32_t iIP = (uint32_t)inet_addr(sIP.c_str()); + uint64_t llNodeID = (((uint64_t)iIP) << 32) | iPort; + + ScopedLock oLockGuard(m_oMutex); + + auto it = m_mapEvent.find(llNodeID); + if (it != end(m_mapEvent)) + { + return it->second; + } + + return CreateEvent(llNodeID, sIP, iPort); +} + +MessageEvent * TcpClient :: CreateEvent(const uint64_t llNodeID, const std::string & sIP, const int iPort) +{ + PLImp("start, ip %s port %d", sIP.c_str(), iPort); + + Socket oSocket; + oSocket.setNonBlocking(true); + oSocket.setNoDelay(true); + SocketAddress oAddr(sIP, iPort); + oSocket.connect(oAddr); + + MessageEvent * poEvent = new MessageEvent(MessageEventType_SEND, oSocket.detachSocketHandle(), + oAddr, m_poEventLoop, m_poNetWork); + assert(poEvent != nullptr); + + m_mapEvent[llNodeID] = poEvent; + m_vecEvent.push_back(poEvent); + + PLImp("ok, ip %s port %d", sIP.c_str(), iPort); + + return poEvent; +} + +void TcpClient :: DealWithWrite() +{ + size_t iSize = m_vecEvent.size(); + + for (size_t i = 0; i < iSize; i++) + { + m_vecEvent[i]->OpenWrite(); + } + //PLImp("end, live event count %zu", vecEventList.size()); +} + +} + diff --git a/src/communicate/tcp/tcp_client.h b/src/communicate/tcp/tcp_client.h new file mode 100644 index 000000000..9aa73258b --- /dev/null +++ b/src/communicate/tcp/tcp_client.h @@ -0,0 +1,63 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include "message_event.h" +#include "utils_include.h" + +namespace phxpaxos +{ + +class EventLoop; +class NetWork; + +class TcpClient +{ +public: + TcpClient( + EventLoop * poEventLoop, + NetWork * poNetWork); + ~TcpClient(); + + int AddMessage(const std::string & sIP, const int iPort, const std::string & sMessage); + + void DealWithWrite(); + +private: + MessageEvent * GetEvent(const std::string & sIP, const int iPort); + + MessageEvent * CreateEvent(const uint64_t llNodeID, const std::string & sIP, const int iPort); + +private: + EventLoop * m_poEventLoop; + NetWork * m_poNetWork; + +private: + std::map m_mapEvent; + std::vector m_vecEvent; + Mutex m_oMutex; + +}; + +} diff --git a/src/communicate/udp.cpp b/src/communicate/udp.cpp new file mode 100644 index 000000000..372962808 --- /dev/null +++ b/src/communicate/udp.cpp @@ -0,0 +1,221 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "udp.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "dfnetwork.h" +#include "comm_include.h" +#include + +namespace phxpaxos +{ + +UDPRecv :: UDPRecv(DFNetWork * poDFNetWork) + : m_poDFNetWork(poDFNetWork), m_iSockFD(-1), m_bIsEnd(false) +{ +} + +UDPRecv :: ~UDPRecv() +{ +} + +void UDPRecv :: Stop() +{ + m_bIsEnd = true; + join(); +} + +int UDPRecv :: Init(const int iPort) +{ + if ((m_iSockFD = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + return -1; + } + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + + addr.sin_family = AF_INET; + addr.sin_port = htons(iPort); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if (bind(m_iSockFD, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + return -1; + } + + return 0; +} + +void UDPRecv :: run() +{ + char sBuffer[65536] = {0}; + + struct sockaddr_in addr; + socklen_t addr_len = sizeof(struct sockaddr_in); + memset(&addr, 0, sizeof(addr)); + + while(true) + { + if (m_bIsEnd) + { + PLHead("UDPRecv [END]"); + return; + } + + struct pollfd fd; + int ret; + + fd.fd = m_iSockFD; + fd.events = POLLIN; + ret = poll(&fd, 1, 500); + + if (ret == 0 || ret == -1) + { + continue; + } + + int iRecvLen = recvfrom(m_iSockFD, sBuffer, sizeof(sBuffer), 0, + (struct sockaddr *)&addr, &addr_len); + + //printf("recvlen %d, buffer %s client %s\n", + //iRecvLen, sBuffer, inet_ntoa(addr.sin_addr)); + + BP->GetNetworkBP()->UDPReceive(iRecvLen); + + if (iRecvLen > 0) + { + m_poDFNetWork->OnReceiveMessage(sBuffer, iRecvLen); + } + } +} + +////////////////////////////////////////////// + +UDPSend :: UDPSend() : m_iSockFD(-1), m_bIsEnd(false) +{ +} + +UDPSend :: ~UDPSend() +{ + while (!m_oSendQueue.empty()) + { + QueueData * poData = m_oSendQueue.peek(); + m_oSendQueue.pop(); + delete poData; + } +} + +int UDPSend :: Init() +{ + if ((m_iSockFD = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + return -1; + } + + return 0; +} + +void UDPSend :: Stop() +{ + m_bIsEnd = true; + join(); +} + +void UDPSend :: SendMessage(const std::string & sIP, const int iPort, const std::string & sMessage) +{ + struct sockaddr_in addr; + int addr_len = sizeof(struct sockaddr_in); + memset(&addr, 0, sizeof(addr)); + + addr.sin_family = AF_INET; + addr.sin_port = htons(iPort); + addr.sin_addr.s_addr = inet_addr(sIP.c_str()); + + sendto(m_iSockFD, sMessage.data(), (int)sMessage.size(), 0, (struct sockaddr *)&addr, addr_len); + + BP->GetNetworkBP()->UDPRealSend(sMessage); +} + +void UDPSend :: run() +{ + while(true) + { + QueueData * poData = nullptr; + + m_oSendQueue.lock(); + + bool bSucc = m_oSendQueue.peek(poData, 1000); + if (bSucc) + { + m_oSendQueue.pop(); + } + + m_oSendQueue.unlock(); + + if (poData != nullptr) + { + SendMessage(poData->m_sIP, poData->m_iPort, poData->m_sMessage); + delete poData; + } + + if (m_bIsEnd) + { + PLHead("UDPSend [END]"); + return; + } + } +} + +int UDPSend :: AddMessage(const std::string & sIP, const int iPort, const std::string & sMessage) +{ + m_oSendQueue.lock(); + + if ((int)m_oSendQueue.size() > UDP_QUEUE_MAXLEN) + { + BP->GetNetworkBP()->UDPQueueFull(); + PLErr("queue length %d too long, can't enqueue", m_oSendQueue.size()); + + m_oSendQueue.unlock(); + + return -2; + } + + QueueData * poData = new QueueData; + poData->m_sIP = sIP; + poData->m_iPort = iPort; + poData->m_sMessage = sMessage; + + m_oSendQueue.add(poData); + m_oSendQueue.unlock(); + + return 0; +} + +} + diff --git a/src/communicate/udp.h b/src/communicate/udp.h new file mode 100644 index 000000000..760783739 --- /dev/null +++ b/src/communicate/udp.h @@ -0,0 +1,79 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "utils_include.h" + +namespace phxpaxos +{ + +class DFNetWork; + +class UDPRecv : public Thread +{ +public: + UDPRecv(DFNetWork * poDFNetWork); + ~UDPRecv(); + + int Init(const int iPort); + + void run(); + + void Stop(); + +private: + DFNetWork * m_poDFNetWork; + int m_iSockFD; + bool m_bIsEnd; +}; + +class UDPSend : public Thread +{ +public: + UDPSend(); + ~UDPSend(); + + int Init(); + + void run(); + + void Stop(); + + int AddMessage(const std::string & sIP, const int iPort, const std::string & sMessage); + + struct QueueData + { + std::string m_sIP; + int m_iPort; + std::string m_sMessage; + }; + +private: + void SendMessage(const std::string & sIP, const int iPort, const std::string & sMessage); + +private: + Queue m_oSendQueue; + int m_iSockFD; + bool m_bIsEnd; +}; + +} diff --git a/src/config/Makefile.define b/src/config/Makefile.define new file mode 100644 index 000000000..4807a96f6 --- /dev/null +++ b/src/config/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libconfig.a + +CONFIG_OBJ=config.o system_v_sm.o + +CONFIG_LIB=config src/comm:comm src/logstorage:logstorage src/sm-base:smbase include:include + +CONFIG_SYS_LIB= + +CONFIG_INCS=$(SRC_BASE_PATH)/src/config + +CONFIG_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/config/config.cpp b/src/config/config.cpp new file mode 100644 index 000000000..8f272fc08 --- /dev/null +++ b/src/config/config.cpp @@ -0,0 +1,253 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "config.h" +#include +#include "inttypes.h" +#include "comm_include.h" + +namespace phxpaxos +{ + +Config :: Config( + const LogStorage * poLogStorage, + const bool bUseMembership, + const NodeInfo & oMyNode, + const NodeInfoList & vecNodeInfoList, + const FollowerNodeInfoList & vecFollowerNodeInfoList, + const int iMyGroupIdx, + const int iGroupCount, + MembershipChangeCallback pMembershipChangeCallback) + : m_bUseMembership(bUseMembership), + m_iMyNodeID(oMyNode.GetNodeID()), + m_iNodeCount(vecNodeInfoList.size()), + m_iMyGroupIdx(iMyGroupIdx), + m_iGroupCount(iGroupCount), + m_oSystemVSM(iMyGroupIdx, oMyNode.GetNodeID(), poLogStorage, pMembershipChangeCallback), + m_poMasterSM(nullptr) +{ + m_vecNodeInfoList = vecNodeInfoList; + + m_bIsIMFollower = false; + m_iFollowToNodeID = nullnode; + + for (auto & oFollowerNodeInfo : vecFollowerNodeInfoList) + { + if (oFollowerNodeInfo.oMyNode.GetNodeID() == oMyNode.GetNodeID()) + { + PLG1Head("I'm follower, ip %s port %d nodeid %lu", + oMyNode.GetIP().c_str(), oMyNode.GetPort(), oMyNode.GetNodeID()); + m_bIsIMFollower = true; + m_iFollowToNodeID = oFollowerNodeInfo.oFollowNode.GetNodeID(); + + InsideOptions::Instance()->SetAsFollower(); + } + } +} + +Config :: ~Config() +{ +} + +int Config :: Init() +{ + int ret = m_oSystemVSM.Init(); + if (ret != 0) + { + PLG1Err("fail, ret %d", ret); + return ret; + } + + m_oSystemVSM.AddNodeIDList(m_vecNodeInfoList); + + PLG1Head("OK"); + return 0; +} + +const bool Config :: CheckConfig() +{ + if (!m_oSystemVSM.IsIMInMembership()) + { + PLG1Err("my node %lu is not in membership", m_iMyNodeID); + return false; + } + + return true; +} + +const uint64_t Config :: GetGid() const +{ + return m_oSystemVSM.GetGid(); +} + +const nodeid_t Config :: GetMyNodeID() const +{ + return m_iMyNodeID; +} + +const int Config :: GetNodeCount() const +{ + return m_oSystemVSM.GetNodeCount(); +} + +const int Config :: GetMyGroupIdx() const +{ + return m_iMyGroupIdx; +} + +const int Config :: GetGroupCount() const +{ + return m_iGroupCount; +} + +const int Config :: GetMajorityCount() const +{ + return m_oSystemVSM.GetMajorityCount(); +} + +const bool Config :: GetIsUseMembership() const +{ + return m_bUseMembership; +} + +//////////////////////////////////////////////////////////// + +const uint64_t Config :: GetAskforLearnTimeoutMs() const +{ + return 2000; +} + +const int Config :: GetPrepareTimeoutMs() const +{ + return 3000; +} + +const int Config :: GetAcceptTimeoutMs() const +{ + return 3000; +} + +/////////////////////////////////////////////////////////// + +const bool Config :: IsValidNodeID(const nodeid_t iNodeID) +{ + return m_oSystemVSM.IsValidNodeID(iNodeID); +} + +const bool Config :: IsIMFollower() const +{ + return m_bIsIMFollower; +} + +const nodeid_t Config :: GetFollowToNodeID() const +{ + return m_iFollowToNodeID; +} + +/////////////////////////////////////////////////////// + +SystemVSM * Config :: GetSystemVSM() +{ + return &m_oSystemVSM; +} + +/////////////////////////////////////////////////////// + +void Config :: SetMasterSM(InsideSM * poMasterSM) +{ + m_poMasterSM = poMasterSM; +} + +InsideSM * Config :: GetMasterSM() +{ + return m_poMasterSM; +} + +/////////////////////////////////////////////////////// + +#define TmpNodeTimeout 60000 + +void Config :: AddTmpNodeOnlyForLearn(const nodeid_t iTmpNodeID) +{ + const std::set & setNodeID = m_oSystemVSM.GetMembershipMap(); + if (setNodeID.find(iTmpNodeID) != end(setNodeID)) + { + return; + } + + m_mapTmpNodeOnlyForLearn[iTmpNodeID] = Time::GetTimestampMS() + TmpNodeTimeout; +} + +const std::map & Config :: GetTmpNodeMap() +{ + uint64_t llNowTime = Time::GetTimestampMS(); + + for (auto it = m_mapTmpNodeOnlyForLearn.begin(); it != end(m_mapTmpNodeOnlyForLearn);) + { + if (it->second < llNowTime) + { + PLErr("tmpnode %lu timeout, nowtimems %lu tmpnode last add time %lu", + it->first, llNowTime, it->second); + it = m_mapTmpNodeOnlyForLearn.erase(it); + } + else + { + it++; + } + } + + return m_mapTmpNodeOnlyForLearn; +} + +void Config :: AddFollowerNode(const nodeid_t iMyFollowerNodeID) +{ + static int iFollowerTimeout = ASKFORLEARN_NOOP_INTERVAL * 3; + m_mapMyFollower[iMyFollowerNodeID] = Time::GetTimestampMS() + iFollowerTimeout; +} + +const std::map & Config :: GetMyFollowerMap() +{ + uint64_t llNowTime = Time::GetTimestampMS(); + + for (auto it = m_mapMyFollower.begin(); it != end(m_mapMyFollower);) + { + if (it->second < llNowTime) + { + PLErr("follower %lu timeout, nowtimems %lu tmpnode last add time %lu", + it->first, llNowTime, it->second); + it = m_mapMyFollower.erase(it); + } + else + { + it++; + } + } + + return m_mapMyFollower; +} + +const size_t Config :: GetMyFollowerCount() +{ + return m_mapMyFollower.size(); +} + +} + diff --git a/src/config/config.h b/src/config/config.h new file mode 100644 index 000000000..78f875bab --- /dev/null +++ b/src/config/config.h @@ -0,0 +1,120 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include "commdef.h" +#include "system_v_sm.h" + +namespace phxpaxos +{ + +class Config +{ +public: + Config( + const LogStorage * poLogStorage, + const bool bUseMembership, + const NodeInfo & oMyNode, + const NodeInfoList & vecNodeInfoList, + const FollowerNodeInfoList & vecFollowerNodeInfoList, + const int iMyGroupIdx, + const int iGroupCount, + MembershipChangeCallback pMembershipChangeCallback); + + ~Config(); + + int Init(); + + const bool CheckConfig(); + +public: + SystemVSM * GetSystemVSM(); + +public: + const uint64_t GetGid() const; + + const nodeid_t GetMyNodeID() const; + + const int GetNodeCount() const; + + const int GetMyGroupIdx() const; + + const int GetGroupCount() const; + + const int GetMajorityCount() const; + + const bool GetIsUseMembership() const; + +public: + const int GetPrepareTimeoutMs() const; + + const int GetAcceptTimeoutMs() const; + + const uint64_t GetAskforLearnTimeoutMs() const; + +public: + const bool IsValidNodeID(const nodeid_t iNodeID); + + const bool IsIMFollower() const; + + const nodeid_t GetFollowToNodeID() const; + +public: + void SetMasterSM(InsideSM * poMasterSM); + + InsideSM * GetMasterSM(); + +public: + void AddTmpNodeOnlyForLearn(const nodeid_t iTmpNodeID); + + //this function only for communicate. + const std::map & GetTmpNodeMap(); + + void AddFollowerNode(const nodeid_t iMyFollowerNodeID); + + //this function only for communicate. + const std::map & GetMyFollowerMap(); + + const size_t GetMyFollowerCount(); + +private: + bool m_bUseMembership; + + nodeid_t m_iMyNodeID; + int m_iNodeCount; + int m_iMyGroupIdx; + int m_iGroupCount; + + NodeInfoList m_vecNodeInfoList; + + bool m_bIsIMFollower; + nodeid_t m_iFollowToNodeID; + + SystemVSM m_oSystemVSM; + InsideSM * m_poMasterSM; + + std::map m_mapTmpNodeOnlyForLearn; + std::map m_mapMyFollower; +}; + +} diff --git a/src/config/config_include.h b/src/config/config_include.h new file mode 100644 index 000000000..66352a637 --- /dev/null +++ b/src/config/config_include.h @@ -0,0 +1,26 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "./config.h" +#include "./system_v_sm.h" +#include "./inside_sm.h" diff --git a/src/config/inside_sm.h b/src/config/inside_sm.h new file mode 100644 index 000000000..fc2a70780 --- /dev/null +++ b/src/config/inside_sm.h @@ -0,0 +1,40 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/sm.h" +#include + +namespace phxpaxos +{ + +class InsideSM : public StateMachine +{ +public: + virtual ~InsideSM() {} + + virtual int GetCheckpointBuffer(std::string & sCPBuffer) = 0; + + virtual int UpdateByCheckpoint(const std::string & sCPBuffer, bool & bChange) = 0; +}; + +} diff --git a/src/config/system_v_sm.cpp b/src/config/system_v_sm.cpp new file mode 100644 index 000000000..4777b69a0 --- /dev/null +++ b/src/config/system_v_sm.cpp @@ -0,0 +1,366 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "system_v_sm.h" +#include "commdef.h" +#include +#include "msg_transport.h" + +namespace phxpaxos +{ + +SystemVSM :: SystemVSM( + const int iGroupIdx, + const nodeid_t iMyNodeID, + const LogStorage * poLogStorage, + MembershipChangeCallback pMembershipChangeCallback) + : m_iMyGroupIdx(iGroupIdx), m_oSystemVStore(poLogStorage), + m_iMyNodeID(iMyNodeID), m_pMembershipChangeCallback(pMembershipChangeCallback) +{ +} + +SystemVSM :: ~SystemVSM() +{ +} + +int SystemVSM :: Init() +{ + int ret = m_oSystemVStore.Read(m_iMyGroupIdx, m_oSystemVariables); + if (ret != 0 && ret != 1) + { + return ret; + } + + if (ret == 1) + { + m_oSystemVariables.set_gid(0); + m_oSystemVariables.set_version(-1); + PLG1Imp("variables not exist"); + } + else + { + RefleshNodeID(); + PLG1Imp("OK, gourpidx %d gid %lu version %lu", + m_iMyGroupIdx, m_oSystemVariables.gid(), m_oSystemVariables.version()); + } + + return 0; +} + +int SystemVSM :: UpdateSystemVariables(const SystemVariables & oVariables) +{ + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + + int ret = m_oSystemVStore.Write(oWriteOptions, m_iMyGroupIdx, oVariables); + if (ret != 0) + { + PLG1Err("SystemVStore::Write fail, ret %d", ret); + return -1; + } + + m_oSystemVariables = oVariables; + + RefleshNodeID(); + + return 0; +} + +bool SystemVSM :: Execute(const int iGroupIdx, const uint64_t llInstanceID, const std::string & sValue, SMCtx * poSMCtx) +{ + SystemVariables oVariables; + bool bSucc = oVariables.ParseFromArray(sValue.data(), sValue.size()); + if (!bSucc) + { + PLG1Err("Variables.ParseFromArray fail, bufferlen %zu", sValue.size()); + return false; + } + + int * smret = nullptr; + if (poSMCtx != nullptr && poSMCtx->m_pCtx != nullptr) + { + smret = (int *)poSMCtx->m_pCtx; + } + + if (m_oSystemVariables.gid() != 0 && oVariables.gid() != m_oSystemVariables.gid()) + { + PLG1Err("modify.gid %lu not equal to now.gid %lu", oVariables.gid(), m_oSystemVariables.gid()); + if (smret != nullptr) *smret = Paxos_MembershipOp_GidNotSame; + return true; + } + + if (oVariables.version() != m_oSystemVariables.version()) + { + PLG1Err("modify.version %lu not equal to now.version %lu", oVariables.version(), m_oSystemVariables.version()); + if (smret != nullptr) *smret = Paxos_MembershipOp_VersionConflit; + return true; + } + + oVariables.set_version(llInstanceID); + int ret = UpdateSystemVariables(oVariables); + if (ret != 0) + { + return false; + } + + PLG1Head("OK, new version %lu gid %lu", m_oSystemVariables.version(), m_oSystemVariables.gid()); + + if (smret != nullptr) *smret = 0; + + return true; +} + +////////////////////////////////////////////////// + +const uint64_t SystemVSM :: GetGid() const +{ + return m_oSystemVariables.gid(); +} + +void SystemVSM :: GetMembership(NodeInfoList & vecNodeInfoList, uint64_t & llVersion) +{ + //must must get version first! + llVersion = m_oSystemVariables.version(); + + for (int i = 0; i < m_oSystemVariables.membership_size(); i++) + { + PaxosNodeInfo oNodeInfo = m_oSystemVariables.membership(i); + + NodeInfo tTmpNode(oNodeInfo.nodeid()); + vecNodeInfoList.push_back(tTmpNode); + } +} + +int SystemVSM :: Membership_OPValue(const NodeInfoList & vecNodeInfoList, const uint64_t llVersion, std::string & sOpValue) +{ + SystemVariables oVariables; + //must must set version first! + oVariables.set_version(llVersion); + oVariables.set_gid(m_oSystemVariables.gid()); + + for (auto & tNodeInfo : vecNodeInfoList) + { + PaxosNodeInfo * poNodeInfo = oVariables.add_membership(); + //to do, what rid? + poNodeInfo->set_rid(0); + poNodeInfo->set_nodeid(tNodeInfo.GetNodeID()); + } + + bool sSucc = oVariables.SerializeToString(&sOpValue); + if (!sSucc) + { + PLG1Err("Variables.Serialize fail"); + return -1; + } + + return 0; +} + +int SystemVSM :: CreateGid_OPValue(const uint64_t llGid, std::string & sOpValue) +{ + SystemVariables oVariables = m_oSystemVariables; + oVariables.set_gid(llGid); + + /* + ** only founder need to check this. but now all is founder. + if (oVariables.membership_size() == 0) + { + PLG1Err("no membership, can't create gid"); + return -1; + } + */ + + bool sSucc = oVariables.SerializeToString(&sOpValue); + if (!sSucc) + { + PLG1Err("Variables.Serialize fail"); + return -1; + } + + return 0; +} + +///////////////////////////////////////////////// + +void SystemVSM :: AddNodeIDList(const NodeInfoList & vecNodeInfoList) +{ + if (m_oSystemVariables.gid() != 0) + { + PLG1Err("No need to add, i already have membership info."); + return; + } + + m_setNodeID.clear(); + m_oSystemVariables.clear_membership(); + + for (auto & tNodeInfo : vecNodeInfoList) + { + PaxosNodeInfo * poNodeInfo = m_oSystemVariables.add_membership(); + //to do, what rid? + poNodeInfo->set_rid(0); + poNodeInfo->set_nodeid(tNodeInfo.GetNodeID()); + + NodeInfo tTmpNode(poNodeInfo->nodeid()); + } + + RefleshNodeID(); +} + +void SystemVSM :: RefleshNodeID() +{ + m_setNodeID.clear(); + + NodeInfoList vecNodeInfoList; + + for (int i = 0; i < m_oSystemVariables.membership_size(); i++) + { + PaxosNodeInfo oNodeInfo = m_oSystemVariables.membership(i); + NodeInfo tTmpNode(oNodeInfo.nodeid()); + + PLG1Head("ip %s port %d nodeid %lu", + tTmpNode.GetIP().c_str(), tTmpNode.GetPort(), tTmpNode.GetNodeID()); + + m_setNodeID.insert(tTmpNode.GetNodeID()); + + vecNodeInfoList.push_back(tTmpNode); + } + + if (m_pMembershipChangeCallback != nullptr) + { + m_pMembershipChangeCallback(m_iMyGroupIdx, vecNodeInfoList); + } +} + +const int SystemVSM :: GetNodeCount() const +{ + return (int)m_setNodeID.size(); +} + +const int SystemVSM :: GetMajorityCount() const +{ + return (int)(floor((double)GetNodeCount() / 2) + 1); +} + +const bool SystemVSM :: IsValidNodeID(const nodeid_t iNodeID) +{ + if (m_oSystemVariables.gid() == 0) + { + return true; + } + + return m_setNodeID.find(iNodeID) != end(m_setNodeID); +} + +const bool SystemVSM :: IsIMInMembership() +{ + return IsValidNodeID(m_iMyNodeID); +} + +/////////////////////////////////////////////////////////////////////////////// + +int SystemVSM :: GetCheckpointBuffer(std::string & sCPBuffer) +{ + if (m_oSystemVariables.version() == (uint64_t)-1 + || m_oSystemVariables.gid() == 0) + { + return 0; + } + + bool sSucc = m_oSystemVariables.SerializeToString(&sCPBuffer); + if (!sSucc) + { + PLG1Err("Variables.Serialize fail"); + return -1; + } + + return 0; +} + +int SystemVSM :: UpdateByCheckpoint(const std::string & sCPBuffer, bool & bChange) +{ + if (sCPBuffer.size() == 0) + { + return 0; + } + + bChange = false; + + SystemVariables oVariables; + bool bSucc = oVariables.ParseFromArray(sCPBuffer.data(), sCPBuffer.size()); + if (!bSucc) + { + PLG1Err("Variables.ParseFromArray fail, bufferlen %zu", sCPBuffer.size()); + return -1; + } + + if (oVariables.version() == (uint64_t)-1) + { + PLG1Err("variables.version not init, this is not checkpoint"); + return -2; + } + + if (m_oSystemVariables.gid() != 0 + && oVariables.gid() != m_oSystemVariables.gid()) + { + PLG1Err("gid not same, cp.gid %lu now.gid %lu", oVariables.gid(), m_oSystemVariables.gid()); + return -2; + } + + if (m_oSystemVariables.version() != (uint64_t)-1 + && oVariables.version() <= m_oSystemVariables.version()) + { + PLG1Imp("lag checkpoint, no need update, cp.version %lu now.version %lu", + oVariables.version(), m_oSystemVariables.version()); + return 0; + } + + bChange = true; + SystemVariables oOldVariables = m_oSystemVariables; + + int ret = UpdateSystemVariables(oVariables); + if (ret != 0) + { + return -1; + } + + PLG1Head("ok, cp.version %lu cp.membercount %d old.version %lu old.membercount %d", + oVariables.version(), oVariables.membership_size(), + oOldVariables.version(), oOldVariables.membership_size()); + + return 0; +} + +/////////////////////////////////////////////////////////////////////// + +void SystemVSM :: GetSystemVariables(SystemVariables & oVariables) +{ + oVariables = m_oSystemVariables; +} + +/////////////////////////////////////////////////////////////////////// + +const std::set & SystemVSM :: GetMembershipMap() +{ + return m_setNodeID; +} + +} + diff --git a/src/config/system_v_sm.h b/src/config/system_v_sm.h new file mode 100644 index 000000000..1275eadb9 --- /dev/null +++ b/src/config/system_v_sm.h @@ -0,0 +1,118 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "system_variables_store.h" +#include "phxpaxos/sm.h" +#include "commdef.h" +#include "inside_sm.h" +#include + +namespace phxpaxos +{ + +class MsgTransport; + +class SystemVSM : public InsideSM +{ +public: + SystemVSM( + const int iGroupIdx, + const nodeid_t iMyNodeID, + const LogStorage * poLogStorage, + MembershipChangeCallback pMembershipChangeCallback); + ~SystemVSM(); + + int Init(); + + bool Execute(const int iGroupIdx, const uint64_t llInstanceID, const std::string & sValue, SMCtx * poSMCtx); + + const int SMID() const {return SYSTEM_V_SMID;} + +public: + const uint64_t GetGid() const; + + void GetMembership(NodeInfoList & vecNodeInfoList, uint64_t & llVersion); + + int CreateGid_OPValue(const uint64_t llGid, std::string & sOpValue); + + int Membership_OPValue(const NodeInfoList & vecNodeInfoList, const uint64_t llVersion, std::string & sOpValue); + +public: + //membership + + void AddNodeIDList(const NodeInfoList & vecNodeInfoList); + + void RefleshNodeID(); + + const int GetNodeCount() const; + + const int GetMajorityCount() const; + + const bool IsValidNodeID(const nodeid_t iNodeID); + + const bool IsIMInMembership(); + +public: + const uint64_t GetCheckpointInstanceID(const int iGroupIdx) const { return m_oSystemVariables.version(); } + + bool ExecuteForCheckpoint(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue) { return true; } + + int GetCheckpointState(const int iGroupIdx, std::string & sDirPath, + std::vector & vecFileList) { return 0; } + + int LoadCheckpointState(const int iGroupIdx, const std::string & sCheckpointTmpFileDirPath, + const std::vector & vecFileList, const uint64_t llCheckpointInstanceID) { return 0; } + + int LockCheckpointState() { return 0; } + + void UnLockCheckpointState() { } + +public: + int GetCheckpointBuffer(std::string & sCPBuffer); + + int UpdateByCheckpoint(const std::string & sCPBuffer, bool & bChange); + +public: + //for tools + void GetSystemVariables(SystemVariables & oVariables); + + int UpdateSystemVariables(const SystemVariables & oVariables); + +public: + //this function only for communicate. + const std::set & GetMembershipMap(); + +private: + int m_iMyGroupIdx; + SystemVariables m_oSystemVariables; + SystemVariablesStore m_oSystemVStore; + + std::set m_setNodeID; + + nodeid_t m_iMyNodeID; + + MembershipChangeCallback m_pMembershipChangeCallback; +}; + +} diff --git a/src/logstorage/Makefile.define b/src/logstorage/Makefile.define new file mode 100644 index 000000000..a8b61fdde --- /dev/null +++ b/src/logstorage/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=liblogstorage.a + +LOGSTORAGE_OBJ=db.o paxos_log.o log_store.o system_variables_store.o + +LOGSTORAGE_LIB=logstorage src/comm:comm include:include + +LOGSTORAGE_SYS_LIB=$(LEVELDB_LIB_PATH)/libleveldb.a + +LOGSTORAGE_INCS=$(SRC_BASE_PATH)/src/logstorage $(LEVELDB_INCLUDE_PATH) + +LOGSTORAGE_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/logstorage/db.cpp b/src/logstorage/db.cpp new file mode 100644 index 000000000..9e3c7e79f --- /dev/null +++ b/src/logstorage/db.cpp @@ -0,0 +1,778 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "db.h" +#include "commdef.h" + +namespace phxpaxos +{ + +int PaxosComparator :: Compare(const leveldb::Slice & a, const leveldb::Slice & b) const +{ + return PCompare(a, b); +} + +int PaxosComparator :: PCompare(const leveldb::Slice & a, const leveldb::Slice & b) +{ + assert(a.size() == sizeof(uint64_t)); + assert(b.size() == sizeof(uint64_t)); + + uint64_t lla = 0; + uint64_t llb = 0; + + memcpy(&lla, a.data(), sizeof(uint64_t)); + memcpy(&llb, b.data(), sizeof(uint64_t)); + + if (lla == llb) + { + return 0; + } + + return lla < llb ? -1 : 1; +} + +//////////////////////// + +Database :: Database() : m_poLevelDB(nullptr), m_poValueStore(nullptr) +{ + m_bHasInit = false; +} + +Database :: ~Database() +{ + delete m_poValueStore; + delete m_poLevelDB; + + PLG1Head("LevelDB Deleted. Path %s", m_sDBPath.c_str()); +} + +int Database :: ClearAllLog() +{ + string sSystemVariablesBuffer; + int ret = GetSystemVariables(sSystemVariablesBuffer); + if (ret != 0 && ret != 1) + { + PLG1Err("GetSystemVariables fail, ret %d", ret); + return ret; + } + + string sMasterVariablesBuffer; + ret = GetMasterVariables(sMasterVariablesBuffer); + if (ret != 0 && ret != 1) + { + PLG1Err("GetMasterVariables fail, ret %d", ret); + return ret; + } + + m_bHasInit = false; + + delete m_poLevelDB; + m_poLevelDB = nullptr; + + delete m_poValueStore; + m_poValueStore = nullptr; + + string sBakPath = m_sDBPath + ".bak"; + + FileUtils::DeleteDir(sBakPath); + + ret = rename(m_sDBPath.c_str(), sBakPath.c_str()); + assert(ret == 0); + + ret = Init(m_sDBPath, m_iMyGroupIdx); + if (ret != 0) + { + PLG1Err("Init again fail, ret %d", ret); + return ret; + } + + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + if (sSystemVariablesBuffer.size() > 0) + { + ret = SetSystemVariables(oWriteOptions, sSystemVariablesBuffer); + if (ret != 0) + { + PLG1Err("SetSystemVariables fail, ret %d", ret); + return ret; + } + } + + if (sMasterVariablesBuffer.size() > 0) + { + ret = SetMasterVariables(oWriteOptions, sMasterVariablesBuffer); + if (ret != 0) + { + PLG1Err("SetMasterVariables fail, ret %d", ret); + return ret; + } + } + + return 0; +} + +int Database :: Init(const std::string & sDBPath, const int iMyGroupIdx) +{ + if (m_bHasInit) + { + return 0; + } + + m_iMyGroupIdx = iMyGroupIdx; + + m_sDBPath = sDBPath; + + leveldb::Options oOptions; + oOptions.create_if_missing = true; + oOptions.comparator = &m_oPaxosCmp; + //oOptions.write_buffer_size = 1024 * 1024 * 10; + + leveldb::Status oStatus = leveldb::DB::Open(oOptions, sDBPath, &m_poLevelDB); + + if (!oStatus.ok()) + { + PLG1Err("Open leveldb fail, db_path %s", sDBPath.c_str()); + return -1; + } + + m_poValueStore = new LogStore(); + assert(m_poValueStore != nullptr); + + int ret = m_poValueStore->Init(sDBPath, iMyGroupIdx); + if (ret != 0) + { + PLG1Err("value store init fail, ret %d", ret); + return -1; + } + + m_bHasInit = true; + + ret = m_poValueStore->RebuildIndex((Database *)this); + if (ret != 0) + { + PLG1Err("rebuild index fail, ret %d", ret); + return -1; + } + + PLG1Imp("OK, db_path %s", sDBPath.c_str()); + + return 0; +} + +const std::string Database :: GetDBPath() +{ + return m_sDBPath; +} + +int Database :: GetMaxInstanceIDFileID(std::string & sFileID) +{ + uint64_t llMaxInstanceID = 0; + int ret = GetMaxInstanceID(llMaxInstanceID); + if (ret != 0 && ret != 1) + { + return ret; + } + + if (ret == 1) + { + sFileID = ""; + return 0; + } + + string sKey = GenKey(llMaxInstanceID); + + leveldb::Status oStatus = m_poLevelDB->Get(leveldb::ReadOptions(), sKey, &sFileID); + if (!oStatus.ok()) + { + if (oStatus.IsNotFound()) + { + BP->GetLogStorageBP()->LevelDBGetNotExist(); + //PLG1Err("LevelDB.Get not found %s", sKey.c_str()); + return 1; + } + + BP->GetLogStorageBP()->LevelDBGetFail(); + PLG1Err("LevelDB.Get fail"); + return -1; + } + + return 0; +} + +int Database :: RebuildOneIndex(const uint64_t llInstanceID, const std::string & sFileID) +{ + string sKey = GenKey(llInstanceID); + + leveldb::WriteOptions oLevelDBWriteOptions; + oLevelDBWriteOptions.sync = false; + + leveldb::Status oStatus = m_poLevelDB->Put(oLevelDBWriteOptions, sKey, sFileID); + if (!oStatus.ok()) + { + BP->GetLogStorageBP()->LevelDBPutFail(); + PLG1Err("LevelDB.Put fail, instanceid %lu valuelen %zu", llInstanceID, sFileID.size()); + return -1; + } + + return 0; +} + +//////////////////////////////////////////////////////////////////////// + +int Database :: GetFromLevelDB(const uint64_t llInstanceID, std::string & sValue) +{ + string sKey = GenKey(llInstanceID); + + leveldb::Status oStatus = m_poLevelDB->Get(leveldb::ReadOptions(), sKey, &sValue); + if (!oStatus.ok()) + { + if (oStatus.IsNotFound()) + { + BP->GetLogStorageBP()->LevelDBGetNotExist(); + PLG1Debug("LevelDB.Get not found, instanceid %lu", llInstanceID); + return 1; + } + + BP->GetLogStorageBP()->LevelDBGetFail(); + PLG1Err("LevelDB.Get fail, instanceid %lu", llInstanceID); + return -1; + } + + return 0; +} + +int Database :: Get(const uint64_t llInstanceID, std::string & sValue) +{ + if (!m_bHasInit) + { + PLG1Err("no init yet"); + return -1; + } + + string sFileID; + int ret = GetFromLevelDB(llInstanceID, sFileID); + if (ret != 0) + { + return ret; + } + + uint64_t llFileInstanceID = 0; + ret = FileIDToValue(sFileID, llFileInstanceID, sValue); + if (ret != 0) + { + BP->GetLogStorageBP()->FileIDToValueFail(); + return ret; + } + + if (llFileInstanceID != llInstanceID) + { + PLG1Err("file instanceid %lu not equal to key.instanceid %lu", llFileInstanceID, llInstanceID); + return -2; + } + + return 0; +} + +int Database :: ValueToFileID(const WriteOptions & oWriteOptions, const uint64_t llInstanceID, const std::string & sValue, std::string & sFileID) +{ + int ret = m_poValueStore->Append(oWriteOptions, llInstanceID, sValue, sFileID); + if (ret != 0) + { + BP->GetLogStorageBP()->ValueToFileIDFail(); + PLG1Err("fail, ret %d", ret); + return ret; + } + + return 0; +} + +int Database :: FileIDToValue(const std::string & sFileID, uint64_t & llInstanceID, std::string & sValue) +{ + int ret = m_poValueStore->Read(sFileID, llInstanceID, sValue); + if (ret != 0) + { + PLG1Err("fail, ret %d", ret); + return ret; + } + + return 0; +} + +int Database :: PutToLevelDB(const bool bSync, const uint64_t llInstanceID, const std::string & sValue) +{ + string sKey = GenKey(llInstanceID); + + leveldb::WriteOptions oLevelDBWriteOptions; + oLevelDBWriteOptions.sync = bSync; + + m_oTimeStat.Point(); + + leveldb::Status oStatus = m_poLevelDB->Put(oLevelDBWriteOptions, sKey, sValue); + if (!oStatus.ok()) + { + BP->GetLogStorageBP()->LevelDBPutFail(); + PLG1Err("LevelDB.Put fail, instanceid %lu valuelen %zu", llInstanceID, sValue.size()); + return -1; + } + + BP->GetLogStorageBP()->LevelDBPutOK(m_oTimeStat.Point()); + + return 0; +} + +int Database :: Put(const WriteOptions & oWriteOptions, const uint64_t llInstanceID, const std::string & sValue) +{ + if (!m_bHasInit) + { + PLG1Err("no init yet"); + return -1; + } + + std::string sFileID; + int ret = ValueToFileID(oWriteOptions, llInstanceID, sValue, sFileID); + if (ret != 0) + { + return ret; + } + + ret = PutToLevelDB(false, llInstanceID, sFileID); + + return ret; +} + +int Database :: ForceDel(const WriteOptions & oWriteOptions, const uint64_t llInstanceID) +{ + if (!m_bHasInit) + { + PLG1Err("no init yet"); + return -1; + } + + string sKey = GenKey(llInstanceID); + string sFileID; + + leveldb::Status oStatus = m_poLevelDB->Get(leveldb::ReadOptions(), sKey, &sFileID); + if (!oStatus.ok()) + { + if (oStatus.IsNotFound()) + { + PLG1Debug("LevelDB.Get not found, instanceid %lu", llInstanceID); + return 0; + } + + PLG1Err("LevelDB.Get fail, instanceid %lu", llInstanceID); + return -1; + } + + int ret = m_poValueStore->ForceDel(sFileID, llInstanceID); + if (ret != 0) + { + return ret; + } + + leveldb::WriteOptions oLevelDBWriteOptions; + oLevelDBWriteOptions.sync = oWriteOptions.bSync; + + oStatus = m_poLevelDB->Delete(oLevelDBWriteOptions, sKey); + if (!oStatus.ok()) + { + PLG1Err("LevelDB.Delete fail, instanceid %lu", llInstanceID); + return -1; + } + + return 0; +} + +int Database :: Del(const WriteOptions & oWriteOptions, const uint64_t llInstanceID) +{ + if (!m_bHasInit) + { + PLG1Err("no init yet"); + return -1; + } + + string sKey = GenKey(llInstanceID); + string sFileID; + + leveldb::Status oStatus = m_poLevelDB->Get(leveldb::ReadOptions(), sKey, &sFileID); + if (!oStatus.ok()) + { + if (oStatus.IsNotFound()) + { + PLG1Debug("LevelDB.Get not found, instanceid %lu", llInstanceID); + return 0; + } + + PLG1Err("LevelDB.Get fail, instanceid %lu", llInstanceID); + return -1; + } + + int ret = m_poValueStore->Del(sFileID, llInstanceID); + if (ret != 0) + { + return ret; + } + + leveldb::WriteOptions oLevelDBWriteOptions; + oLevelDBWriteOptions.sync = oWriteOptions.bSync; + + oStatus = m_poLevelDB->Delete(oLevelDBWriteOptions, sKey); + if (!oStatus.ok()) + { + PLG1Err("LevelDB.Delete fail, instanceid %lu", llInstanceID); + return -1; + } + + return 0; +} + +int Database :: GetMaxInstanceID(uint64_t & llInstanceID) +{ + if (!m_bHasInit) + { + PLG1Err("no init yet"); + return -1; + } + + llInstanceID = MINCHOSEN_KEY; + + leveldb::Iterator * it = m_poLevelDB->NewIterator(leveldb::ReadOptions()); + + it->SeekToLast(); + + while (it->Valid()) + { + llInstanceID = GetInstanceIDFromKey(it->key().ToString()); + if (llInstanceID == MINCHOSEN_KEY + || llInstanceID == SYSTEMVARIABLES_KEY + || llInstanceID == MASTERVARIABLES_KEY) + { + it->Prev(); + } + else + { + delete it; + return 0; + } + } + + delete it; + return 1; +} + +std::string Database :: GenKey(const uint64_t llInstanceID) +{ + string sKey; + sKey.append((char *)&llInstanceID, sizeof(uint64_t)); + return sKey; +} + +const uint64_t Database :: GetInstanceIDFromKey(const std::string & sKey) +{ + uint64_t llInstanceID = 0; + memcpy(&llInstanceID, sKey.data(), sizeof(uint64_t)); + + return llInstanceID; +} + +int Database :: GetMinChosenInstanceID(uint64_t & llMinInstanceID) +{ + if (!m_bHasInit) + { + PLG1Err("no init yet"); + return -1; + } + + static uint64_t llMinKey = MINCHOSEN_KEY; + std::string sValue; + int ret = GetFromLevelDB(llMinKey, sValue); + if (ret != 0 && ret != 1) + { + PLG1Err("fail, ret %d", ret); + return ret; + } + + if (ret == 1) + { + PLG1Err("no min chosen instanceid"); + llMinInstanceID = 0; + return 0; + } + + //old version, minchonsenid store in logstore. + //new version, minchonsenid directly store in leveldb. + if (m_poValueStore->IsValidFileID(sValue)) + { + ret = Get(llMinKey, sValue); + if (ret != 0 && ret != 1) + { + PLG1Err("Get from log store fail, ret %d", ret); + return ret; + } + } + + if (sValue.size() != sizeof(uint64_t)) + { + PLG1Err("fail, mininstanceid size wrong"); + return -2; + } + + memcpy(&llMinInstanceID, sValue.data(), sizeof(uint64_t)); + + PLG1Imp("ok, min chosen instanceid %lu", llMinInstanceID); + + return 0; +} + +int Database :: SetMinChosenInstanceID(const WriteOptions & oWriteOptions, const uint64_t llMinInstanceID) +{ + if (!m_bHasInit) + { + PLG1Err("no init yet"); + return -1; + } + + static uint64_t llMinKey = MINCHOSEN_KEY; + char sValue[sizeof(uint64_t)] = {0}; + memcpy(sValue, &llMinInstanceID, sizeof(uint64_t)); + + int ret = PutToLevelDB(true, llMinKey, string(sValue, sizeof(uint64_t))); + if (ret != 0) + { + return ret; + } + + PLG1Imp("ok, min chosen instanceid %lu", llMinInstanceID); + + return 0; +} + + +int Database :: SetSystemVariables(const WriteOptions & oWriteOptions, const std::string & sBuffer) +{ + static uint64_t llSystemVariablesKey = SYSTEMVARIABLES_KEY; + return PutToLevelDB(true, llSystemVariablesKey, sBuffer); +} + +int Database :: GetSystemVariables(std::string & sBuffer) +{ + static uint64_t llSystemVariablesKey = SYSTEMVARIABLES_KEY; + return GetFromLevelDB(llSystemVariablesKey, sBuffer); +} + +int Database :: SetMasterVariables(const WriteOptions & oWriteOptions, const std::string & sBuffer) +{ + static uint64_t llMasterVariablesKey = MASTERVARIABLES_KEY; + return PutToLevelDB(true, llMasterVariablesKey, sBuffer); +} + +int Database :: GetMasterVariables(std::string & sBuffer) +{ + static uint64_t llMasterVariablesKey = MASTERVARIABLES_KEY; + return GetFromLevelDB(llMasterVariablesKey, sBuffer); +} + +//////////////////////////////////////////////////// + +MultiDatabase :: MultiDatabase() +{ +} + +MultiDatabase :: ~MultiDatabase() +{ + for (auto & poDB : m_vecDBList) + { + delete poDB; + } +} + +int MultiDatabase :: Init(const std::string & sDBPath, const int iGroupCount) +{ + if (access(sDBPath.c_str(), F_OK) == -1) + { + PLErr("DBPath not exist or no limit to open, %s", sDBPath.c_str()); + return -1; + } + + if (iGroupCount < 1 || iGroupCount > 100000) + { + PLErr("Groupcount wrong %d", iGroupCount); + return -2; + } + + std::string sNewDBPath = sDBPath; + + if (sDBPath[sDBPath.size() - 1] != '/') + { + sNewDBPath += '/'; + } + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + char sGroupDBPath[512] = {0}; + snprintf(sGroupDBPath, sizeof(sGroupDBPath), "%sg%d", sNewDBPath.c_str(), iGroupIdx); + + Database * poDB = new Database(); + if (poDB->Init(sGroupDBPath, iGroupIdx) != 0) + { + return -1; + } + + m_vecDBList.push_back(poDB); + } + + PLImp("OK, DBPath %s groupcount %d", sDBPath.c_str(), iGroupCount); + + return 0; +} + +const std::string MultiDatabase :: GetLogStorageDirPath(const int iGroupIdx) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return ""; + } + + return m_vecDBList[iGroupIdx]->GetDBPath(); +} + +int MultiDatabase :: Get(const int iGroupIdx, const uint64_t llInstanceID, std::string & sValue) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->Get(llInstanceID, sValue); +} + +int MultiDatabase :: Put(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID, const std::string & sValue) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->Put(oWriteOptions, llInstanceID, sValue); +} + +int MultiDatabase :: Del(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->Del(oWriteOptions, llInstanceID); +} + +int MultiDatabase :: ForceDel(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->ForceDel(oWriteOptions, llInstanceID); +} + +int MultiDatabase :: GetMaxInstanceID(const int iGroupIdx, uint64_t & llInstanceID) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->GetMaxInstanceID(llInstanceID); +} + +int MultiDatabase :: SetMinChosenInstanceID(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llMinInstanceID) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->SetMinChosenInstanceID(oWriteOptions, llMinInstanceID); +} + +int MultiDatabase :: GetMinChosenInstanceID(const int iGroupIdx, uint64_t & llMinInstanceID) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->GetMinChosenInstanceID(llMinInstanceID); +} + +int MultiDatabase :: ClearAllLog(const int iGroupIdx) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->ClearAllLog(); +} + +int MultiDatabase :: SetSystemVariables(const WriteOptions & oWriteOptions, const int iGroupIdx, const std::string & sBuffer) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->SetSystemVariables(oWriteOptions, sBuffer); +} + +int MultiDatabase :: GetSystemVariables(const int iGroupIdx, std::string & sBuffer) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->GetSystemVariables(sBuffer); +} + +int MultiDatabase :: SetMasterVariables(const WriteOptions & oWriteOptions, const int iGroupIdx, const std::string & sBuffer) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->SetMasterVariables(oWriteOptions, sBuffer); +} + +int MultiDatabase :: GetMasterVariables(const int iGroupIdx, std::string & sBuffer) +{ + if (iGroupIdx >= (int)m_vecDBList.size()) + { + return -2; + } + + return m_vecDBList[iGroupIdx]->GetMasterVariables(sBuffer); +} + +} + diff --git a/src/logstorage/db.h b/src/logstorage/db.h new file mode 100644 index 000000000..728bf94c3 --- /dev/null +++ b/src/logstorage/db.h @@ -0,0 +1,165 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "leveldb/db.h" +#include "leveldb/comparator.h" +#include +#include +#include +#include "comm_include.h" +#include "phxpaxos/storage.h" +#include "log_store.h" + +namespace phxpaxos +{ + +class PaxosComparator : public leveldb::Comparator +{ +public: + int Compare(const leveldb::Slice & a, const leveldb::Slice & b) const; + + static int PCompare(const leveldb::Slice & a, const leveldb::Slice & b); + + const char * Name() const {return "PaxosComparator";} + + void FindShortestSeparator(std::string *, const leveldb::Slice &) const {} + + void FindShortSuccessor(std::string *) const {} +}; + +////////////////////////////////////////// + +#define MINCHOSEN_KEY ((uint64_t)-1) +#define SYSTEMVARIABLES_KEY ((uint64_t)-2) +#define MASTERVARIABLES_KEY ((uint64_t)-3) + +class Database +{ +public: + Database(); + ~Database(); + + int Init(const std::string & sDBPath, const int iMyGroupIdx); + + const std::string GetDBPath(); + + int ClearAllLog(); + + int Get(const uint64_t llInstanceID, std::string & sValue); + + int Put(const WriteOptions & oWriteOptions, const uint64_t llInstanceID, const std::string & sValue); + + int Del(const WriteOptions & oWriteOptions, const uint64_t llInstanceID); + + int ForceDel(const WriteOptions & oWriteOptions, const uint64_t llInstanceID); + + int GetMaxInstanceID(uint64_t & llInstanceID); + + int SetMinChosenInstanceID(const WriteOptions & oWriteOptions, const uint64_t llMinInstanceID); + + int GetMinChosenInstanceID(uint64_t & llMinInstanceID); + + int SetSystemVariables(const WriteOptions & oWriteOptions, const std::string & sBuffer); + + int GetSystemVariables(std::string & sBuffer); + + int SetMasterVariables(const WriteOptions & oWriteOptions, const std::string & sBuffer); + + int GetMasterVariables(std::string & sBuffer); + +public: + int GetMaxInstanceIDFileID(std::string & sFileID); + + int RebuildOneIndex(const uint64_t llInstanceID, const std::string & sFileID); + +private: + int ValueToFileID(const WriteOptions & oWriteOptions, const uint64_t llInstanceID, const std::string & sValue, std::string & sFileID); + + int FileIDToValue(const std::string & sFileID, uint64_t & llInstanceID, std::string & sValue); + + int GetFromLevelDB(const uint64_t llInstanceID, std::string & sValue); + + int PutToLevelDB(const bool bSync, const uint64_t llInstanceID, const std::string & sValue); + +private: + std::string GenKey(const uint64_t llInstanceID); + + const uint64_t GetInstanceIDFromKey(const std::string & sKey); + +private: + leveldb::DB * m_poLevelDB; + PaxosComparator m_oPaxosCmp; + bool m_bHasInit; + + LogStore * m_poValueStore; + std::string m_sDBPath; + + int m_iMyGroupIdx; + +private: + TimeStat m_oTimeStat; +}; + +////////////////////////////////////////// + +class MultiDatabase : public LogStorage +{ +public: + MultiDatabase(); + ~MultiDatabase(); + + int Init(const std::string & sDBPath, const int iGroupCount); + + const std::string GetLogStorageDirPath(const int iGroupIdx); + + int Get(const int iGroupIdx, const uint64_t llInstanceID, std::string & sValue); + + int Put(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID, const std::string & sValue); + + int Del(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID); + + int ForceDel(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID); + + int GetMaxInstanceID(const int iGroupIdx, uint64_t & llInstanceID); + + int SetMinChosenInstanceID(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llMinInstanceID); + + int GetMinChosenInstanceID(const int iGroupIdx, uint64_t & llMinInstanceID); + + int ClearAllLog(const int iGroupIdx); + + int SetSystemVariables(const WriteOptions & oWriteOptions, const int iGroupIdx, const std::string & sBuffer); + + int GetSystemVariables(const int iGroupIdx, std::string & sBuffer); + + int SetMasterVariables(const WriteOptions & oWriteOptions, const int iGroupIdx, const std::string & sBuffer); + + int GetMasterVariables(const int iGroupIdx, std::string & sBuffer); + +private: + std::vector m_vecDBList; +}; + +} + + diff --git a/src/logstorage/log_store.cpp b/src/logstorage/log_store.cpp new file mode 100644 index 000000000..7fda58337 --- /dev/null +++ b/src/logstorage/log_store.cpp @@ -0,0 +1,551 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "log_store.h" +#include +#include +#include +#include +#include "crc32.h" +#include "comm_include.h" +#include "db.h" + +namespace phxpaxos +{ + +LogStore :: LogStore() +{ + m_iFd = -1; + m_iMetaFd = -1; + m_iFileID = -1; + m_iDeletedMaxFileID = -1; +} + +LogStore :: ~LogStore() +{ + if (m_iFd != -1) + { + close(m_iFd); + } + + if (m_iMetaFd != -1) + { + close(m_iMetaFd); + } +} + +int LogStore :: Init(const std::string & sPath, const int iMyGroupIdx) +{ + m_iMyGroupIdx = iMyGroupIdx; + + m_sPath = sPath + "/" + "vfile"; + + if (access(m_sPath.c_str(), F_OK) == -1) + { + if (mkdir(m_sPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) + { + PLG1Err("Create dir fail, path %s", m_sPath.c_str()); + return -1; + } + } + + string sMetaFilePath = m_sPath + "/meta"; + + m_iMetaFd = open(sMetaFilePath.c_str(), O_CREAT | O_RDWR, S_IREAD | S_IWRITE); + if (m_iMetaFd == -1) + { + PLG1Err("open meta file fail, filepath %s", sMetaFilePath.c_str()); + return -1; + } + + lseek(m_iMetaFd, 0, SEEK_SET); + size_t iReadLen = read(m_iMetaFd, &m_iFileID, sizeof(int)); + if (iReadLen != sizeof(int)) + { + if (iReadLen == 0) + { + m_iFileID = 0; + } + else + { + PLG1Err("read meta info fail, readlen %zu", iReadLen); + return -1; + } + } + + uint32_t iMetaChecksum = 0; + iReadLen = read(m_iMetaFd, &iMetaChecksum, sizeof(uint32_t)); + if (iReadLen == sizeof(uint32_t)) + { + uint32_t iCheckSum = crc32(0, (const uint8_t*)(&m_iFileID), sizeof(int)); + if (iCheckSum != iMetaChecksum) + { + PLG1Err("meta file checksum %u not same to cal checksum %u, fileid %d", + iMetaChecksum, iCheckSum, m_iFileID); + return -2; + } + } + + PLG1Head("ok, path %s fileid %d meta checksum %u", m_sPath.c_str(), m_iFileID, iMetaChecksum); + + int ret = OpenFile(m_iFileID, m_iFd); + if (ret != 0) + { + return ret; + } + + return 0; +} + +int LogStore :: IncreaseFileID() +{ + int iFileID = m_iFileID + 1; + uint32_t iCheckSum = crc32(0, (const uint8_t*)(&iFileID), sizeof(int)); + + lseek(m_iMetaFd, 0, SEEK_SET); + size_t iWriteLen = write(m_iMetaFd, (char *)&iFileID, sizeof(int)); + if (iWriteLen != sizeof(int)) + { + PLG1Err("write meta fileid fail, writelen %zu", iWriteLen); + return -1; + } + + iWriteLen = write(m_iMetaFd, (char *)&iCheckSum, sizeof(uint32_t)); + if (iWriteLen != sizeof(uint32_t)) + { + PLG1Err("write meta checksum fail, writelen %zu", iWriteLen); + return -1; + } + + fsync(m_iMetaFd); + + m_iFileID++; + + return 0; +} + +int LogStore :: OpenFile(const int iFileID, int & iFd) +{ + char sFilePath[512] = {0}; + snprintf(sFilePath, sizeof(sFilePath), "%s/%d.f", m_sPath.c_str(), iFileID); + iFd = open(sFilePath, O_CREAT | O_RDWR | O_APPEND, S_IWRITE | S_IREAD); + if (iFd == -1) + { + PLG1Err("open fail fail, filepath %s", sFilePath); + return -1; + } + + PLG1Imp("ok, path %s", sFilePath); + return 0; +} + +int LogStore :: DeleteFile(const int iFileID) +{ + if (iFileID <= m_iDeletedMaxFileID) + { + PLG1Debug("file aready deleted, fileid %d deletedmaxfileid %d", iFileID, m_iDeletedMaxFileID); + return 0; + } + + int ret = 0; + for (int iDeleteFileID = m_iDeletedMaxFileID + 1; iDeleteFileID <= iFileID; iDeleteFileID++) + { + char sFilePath[512] = {0}; + snprintf(sFilePath, sizeof(sFilePath), "%s/%d.f", m_sPath.c_str(), iDeleteFileID); + + ret = access(sFilePath, F_OK); + if (ret == -1) + { + PLG1Err("file aready deleted, filepath %s", sFilePath); + m_iDeletedMaxFileID = iDeleteFileID; + ret = 0; + continue; + } + + ret = remove(sFilePath); + if (ret != 0) + { + PLG1Err("remove fail, filepath %s ret %d", sFilePath, ret); + break; + } + + m_iDeletedMaxFileID = iDeleteFileID; + } + + return ret; +} + +int LogStore :: GetFileFD(int & iFd, int & iFileID, int & iOffset) +{ + iOffset = lseek(m_iFd, 0, SEEK_END); + if (iOffset > LOG_FILE_MAX_SIZE) + { + close(m_iFd); + m_iFd = -1; + + int ret = IncreaseFileID(); + if (ret != 0) + { + return ret; + } + + ret = OpenFile(m_iFileID, m_iFd); + if (ret != 0) + { + return ret; + } + + iOffset = lseek(m_iFd, 0, SEEK_END); + if (iOffset != 0) + { + PLG1Err("IncreaseFileID success, but file exist, data wrong, file size %d", iOffset); + assert(false); + return -1; + } + } + + iFd = m_iFd; + iFileID = m_iFileID; + + return 0; +} + +int LogStore :: Append(const WriteOptions & oWriteOptions, const uint64_t llInstanceID, const std::string & sBuffer, std::string & sFileID) +{ + m_oTimeStat.Point(); + ScopedLock oLock(m_oMutex); + + int iFd = -1; + int iFileID = -1; + int iOffset = -1; + + int ret = GetFileFD(iFd, iFileID, iOffset); + if (ret != 0) + { + return ret; + } + + int iLen = sizeof(uint64_t) + sBuffer.size(); + int iTmpBufferLen = iLen + sizeof(int); + + m_oTmpAppendBuffer.Ready(iTmpBufferLen); + + memcpy(m_oTmpAppendBuffer.GetPtr(), &iLen, sizeof(int)); + memcpy(m_oTmpAppendBuffer.GetPtr() + sizeof(int), &llInstanceID, sizeof(uint64_t)); + memcpy(m_oTmpAppendBuffer.GetPtr() + sizeof(int) + sizeof(uint64_t), sBuffer.c_str(), sBuffer.size()); + + size_t iWriteLen = write(iFd, m_oTmpAppendBuffer.GetPtr(), iTmpBufferLen); + + if (iWriteLen != (size_t)iTmpBufferLen) + { + BP->GetLogStorageBP()->AppendDataFail(); + PLG1Err("writelen %d not equal to %d, buffersize %zu", iWriteLen, iTmpBufferLen, sBuffer.size()); + return -1; + } + + if (oWriteOptions.bSync) + { + fsync(iFd); + } + + int iUseTimeMs = m_oTimeStat.Point(); + BP->GetLogStorageBP()->AppendDataOK(iWriteLen, iUseTimeMs); + + uint32_t iCheckSum = crc32(0, (const uint8_t*)(m_oTmpAppendBuffer.GetPtr() + sizeof(int)), iTmpBufferLen - sizeof(int), CRC32SKIP); + + GenFileID(iFileID, iOffset, iCheckSum, sFileID); + + PLG1Imp("ok, offset %d fileid %d checksum %u instanceid %lu buffer size %zu usetime %dms", + iOffset, iFileID, iCheckSum, llInstanceID, sBuffer.size(), iUseTimeMs); + + return 0; +} + +int LogStore :: Read(const std::string & sFileID, uint64_t & llInstanceID, std::string & sBuffer) +{ + int iFileID = -1; + int iOffset = -1; + uint32_t iCheckSum = 0; + ParseFileID(sFileID, iFileID, iOffset, iCheckSum); + + int iFd = -1; + int ret = OpenFile(iFileID, iFd); + if (ret != 0) + { + return ret; + } + + lseek(iFd, iOffset, SEEK_SET); + + int iLen = 0; + size_t iReadLen = read(iFd, (char *)&iLen, sizeof(int)); + if (iReadLen != sizeof(int)) + { + close(iFd); + PLG1Err("readlen %d not qual to %zu", iReadLen, sizeof(int)); + return -1; + } + + ScopedLock oLock(m_oReadMutex); + + m_oTmpBuffer.Ready(iLen); + iReadLen = read(iFd, m_oTmpBuffer.GetPtr(), iLen); + if (iReadLen != (size_t)iLen) + { + close(iFd); + PLG1Err("readlen %d not qual to %zu", iReadLen, iLen); + return -1; + } + + close(iFd); + + uint32_t iFileCheckSum = crc32(0, (const uint8_t *)m_oTmpBuffer.GetPtr(), iLen, CRC32SKIP); + + if (iFileCheckSum != iCheckSum) + { + BP->GetLogStorageBP()->GetFileChecksumNotEquel(); + PLG1Err("checksum not equal, filechecksum %u checksum %u", iFileCheckSum, iCheckSum); + return -2; + } + + memcpy(&llInstanceID, m_oTmpBuffer.GetPtr(), sizeof(uint64_t)); + sBuffer = string(m_oTmpBuffer.GetPtr() + sizeof(uint64_t), iLen - sizeof(uint64_t)); + + PLG1Imp("ok, fileid %d offset %d instanceid %lu buffer size %zu", + iFileID, iOffset, llInstanceID, sBuffer.size()); + + return 0; +} + +int LogStore :: Del(const std::string & sFileID, const uint64_t llInstanceID) +{ + int iFileID = -1; + int iOffset = -1; + uint32_t iCheckSum = 0; + ParseFileID(sFileID, iFileID, iOffset, iCheckSum); + + if (iFileID > m_iFileID) + { + PLG1Err("del fileid %d large than useing fileid %d", iFileID, m_iFileID); + return -2; + } + + if (iFileID > 0) + { + return DeleteFile(iFileID - 1); + } + + return 0; +} + +int LogStore :: ForceDel(const std::string & sFileID, const uint64_t llInstanceID) +{ + int iFileID = -1; + int iOffset = -1; + uint32_t iCheckSum = 0; + ParseFileID(sFileID, iFileID, iOffset, iCheckSum); + + if (iFileID != m_iFileID) + { + PLG1Err("del fileid %d not equal to fileid %d", iFileID, m_iFileID); + return -2; + } + + char sFilePath[512] = {0}; + snprintf(sFilePath, sizeof(sFilePath), "%s/%d.f", m_sPath.c_str(), iFileID); + + printf("fileid %d offset %d\n", iFileID, iOffset); + + if (truncate(sFilePath, iOffset) != 0) + { + return -1; + } + + return 0; +} + + +void LogStore :: GenFileID(const int iFileID, const int iOffset, const uint32_t iCheckSum, std::string & sFileID) +{ + char sTmp[sizeof(int) + sizeof(int) + sizeof(uint32_t)] = {0}; + memcpy(sTmp, (char *)&iFileID, sizeof(int)); + memcpy(sTmp + sizeof(int), (char *)&iOffset, sizeof(int)); + memcpy(sTmp + sizeof(int) + sizeof(int), (char *)&iCheckSum, sizeof(uint32_t)); + + sFileID = std::string(sTmp, sizeof(int) + sizeof(int) + sizeof(uint32_t)); +} + +void LogStore :: ParseFileID(const std::string & sFileID, int & iFileID, int & iOffset, uint32_t & iCheckSum) +{ + memcpy(&iFileID, (void *)sFileID.c_str(), sizeof(int)); + memcpy(&iOffset, (void *)(sFileID.c_str() + sizeof(int)), sizeof(int)); + memcpy(&iCheckSum, (void *)(sFileID.c_str() + sizeof(int) + sizeof(int)), sizeof(uint32_t)); + + PLG1Debug("fileid %d offset %d checksum %u", iFileID, iOffset, iCheckSum); +} + +const bool LogStore :: IsValidFileID(const std::string & sFileID) +{ + if (sFileID.size() != FILEID_LEN) + { + return false; + } + + return true; +} + +////////////////////////////////////////////////////////////////// + +int LogStore :: RebuildIndex(Database * poDatabase) +{ + string sLastFileID; + + int ret = poDatabase->GetMaxInstanceIDFileID(sLastFileID); + if (ret != 0) + { + return ret; + } + + int iFileID = 0; + int iOffset = 0; + uint32_t iCheckSum = 0; + + if (sLastFileID.size() > 0) + { + ParseFileID(sLastFileID, iFileID, iOffset, iCheckSum); + } + + if (iFileID > m_iFileID) + { + PLG1Err("LevelDB last fileid %d larger than meta now fileid %d, file error", + iFileID, m_iFileID); + return -2; + } + + PLG1Head("START fileid %d offset %d checksum %u", iFileID, iOffset, iCheckSum); + + for (int iNowFileID = iFileID; ;iNowFileID++) + { + ret = RebuildIndexForOneFile(iNowFileID, iOffset, poDatabase); + if (ret != 0 && ret != 1) + { + break; + } + else if (ret == 1) + { + ret = 0; + PLG1Imp("END rebuild ok, nowfileid %d", iNowFileID); + break; + } + + iOffset = 0; + } + + return ret; +} + +int LogStore :: RebuildIndexForOneFile(const int iFileID, const int iOffset, Database * poDatabase) +{ + char sFilePath[512] = {0}; + snprintf(sFilePath, sizeof(sFilePath), "%s/%d.f", m_sPath.c_str(), iFileID); + + int ret = access(sFilePath, F_OK); + if (ret == -1) + { + PLG1Debug("file not exist, filepath %s", sFilePath); + return 1; + } + + int iFd = -1; + ret = OpenFile(iFileID, iFd); + if (ret != 0) + { + return ret; + } + + lseek(iFd, iOffset, SEEK_SET); + + int iNowOffset = iOffset; + bool bNeedTruncate = false; + + while (true) + { + int iLen = 0; + size_t iReadLen = read(iFd, (char *)&iLen, sizeof(int)); + if (iReadLen == 0) + { + PLG1Head("File End, fileid %d offset %d", iFileID, iOffset); + break; + } + + if (iReadLen != sizeof(int)) + { + bNeedTruncate = true; + PLG1Err("readlen %d not qual to %zu, need truncate", iReadLen, sizeof(int)); + break; + } + + m_oTmpBuffer.Ready(iLen); + iReadLen = read(iFd, m_oTmpBuffer.GetPtr(), iLen); + if (iReadLen != (size_t)iLen) + { + bNeedTruncate = true; + PLG1Err("readlen %d not qual to %zu, need truncate", iReadLen, iLen); + break; + } + + + uint64_t llInstanceID = 0; + memcpy(&llInstanceID, m_oTmpBuffer.GetPtr(), sizeof(uint64_t)); + + uint32_t iFileCheckSum = crc32(0, (const uint8_t *)m_oTmpBuffer.GetPtr(), iLen, CRC32SKIP); + + string sFileID; + GenFileID(iFileID, iNowOffset, iFileCheckSum, sFileID); + + ret = poDatabase->RebuildOneIndex(llInstanceID, sFileID); + if (ret != 0) + { + break; + } + + PLG1Imp("rebuild one index ok, fileid %d offset %d instanceid %lu checksum %u buffer size %zu", + iFileID, iNowOffset, llInstanceID, iFileCheckSum, iLen - sizeof(uint64_t)); + + iNowOffset += sizeof(int) + iLen; + } + + close(iFd); + + if (bNeedTruncate) + { + if (truncate(sFilePath, iNowOffset) != 0) + { + PLG1Err("truncate fail, file path %s truncate to length %d", sFilePath, iNowOffset); + return -1; + } + } + + return ret; +} + +} + diff --git a/src/logstorage/log_store.h b/src/logstorage/log_store.h new file mode 100644 index 000000000..0a58a795d --- /dev/null +++ b/src/logstorage/log_store.h @@ -0,0 +1,94 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include "commdef.h" +#include "utils_include.h" +#include "commdef.h" +#include "comm_include.h" + +namespace phxpaxos +{ + +class Database; + +#define FILEID_LEN (sizeof(int) + sizeof(int) + sizeof(uint32_t)) + +class LogStore +{ +public: + LogStore(); + ~LogStore(); + + int Init(const std::string & sPath, const int iMyGroupIdx); + + int Append(const WriteOptions & oWriteOptions, const uint64_t llInstanceID, const std::string & sBuffer, std::string & sFileID); + + int Read(const std::string & sFileID, uint64_t & llInstanceID, std::string & sBuffer); + + int Del(const std::string & sFileID, const uint64_t llInstanceID); + + int ForceDel(const std::string & sFileID, const uint64_t llInstanceID); + + //////////////////////////////////////////// + + const bool IsValidFileID(const std::string & sFileID); + + //////////////////////////////////////////// + + int RebuildIndex(Database * poDatabase); + + int RebuildIndexForOneFile(const int iFileID, const int iOffset, Database * poDatabase); + +private: + void GenFileID(const int iFileID, const int iOffset, const uint32_t iCheckSum, std::string & sFileID); + + void ParseFileID(const std::string & sFileID, int & iFileID, int & iOffset, uint32_t & iCheckSum); + + int IncreaseFileID(); + + int OpenFile(const int iFileID, int & iFd); + + int DeleteFile(const int iFileID); + + int GetFileFD(int & iFd, int & iFileID, int & iOffset); + +private: + int m_iFd; + int m_iMetaFd; + int m_iFileID; + std::string m_sPath; + BytesBuffer m_oTmpBuffer; + BytesBuffer m_oTmpAppendBuffer; + + Mutex m_oMutex; + Mutex m_oReadMutex; + + int m_iDeletedMaxFileID; + int m_iMyGroupIdx; + +private: + TimeStat m_oTimeStat; +}; + +} diff --git a/src/logstorage/paxos_log.cpp b/src/logstorage/paxos_log.cpp new file mode 100644 index 000000000..30a3b677d --- /dev/null +++ b/src/logstorage/paxos_log.cpp @@ -0,0 +1,155 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "paxos_log.h" +#include "db.h" + +namespace phxpaxos +{ + +PaxosLog :: PaxosLog(const LogStorage * poLogStorage) : m_poLogStorage((LogStorage *)poLogStorage) +{ +} + +PaxosLog :: ~PaxosLog() +{ +} + +int PaxosLog :: WriteLog(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID, const std::string & sValue) +{ + const int m_iMyGroupIdx = iGroupIdx; + + AcceptorStateData oState; + oState.set_instanceid(llInstanceID); + oState.set_acceptedvalue(sValue); + oState.set_promiseid(0); + oState.set_promisenodeid(nullnode); + oState.set_acceptedid(0); + oState.set_acceptednodeid(nullnode); + + int ret = WriteState(oWriteOptions, iGroupIdx, llInstanceID, oState); + if (ret != 0) + { + PLG1Err("WriteState to db fail, groupidx %d instanceid %lu ret %d", iGroupIdx, llInstanceID, ret); + return ret; + } + + PLG1Imp("OK, groupidx %d InstanceID %lu valuelen %zu", + iGroupIdx, llInstanceID, sValue.size()); + + return 0; +} + +int PaxosLog :: ReadLog(const int iGroupIdx, const uint64_t llInstanceID, std::string & sValue) +{ + const int m_iMyGroupIdx = iGroupIdx; + + AcceptorStateData oState; + int ret = ReadState(iGroupIdx, llInstanceID, oState); + if (ret != 0) + { + PLG1Err("ReadState from db fail, groupidx %d instanceid %lu ret %d", + iGroupIdx, llInstanceID, ret); + return ret; + + } + + sValue = oState.acceptedvalue(); + + PLG1Imp("OK, groupidx %d InstanceID %lu value %zu", + iGroupIdx, llInstanceID, sValue.size()); + + return 0; +} + +int PaxosLog :: WriteState(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID, const AcceptorStateData & oState) +{ + const int m_iMyGroupIdx = iGroupIdx; + + string sBuffer; + bool sSucc = oState.SerializeToString(&sBuffer); + if (!sSucc) + { + PLG1Err("State.Serialize fail"); + return -1; + } + + int ret = m_poLogStorage->Put(oWriteOptions, iGroupIdx, llInstanceID, sBuffer); + if (ret != 0) + { + PLG1Err("DB.Put fail, groupidx %d bufferlen %zu ret %d", + iGroupIdx, sBuffer.size(), ret); + return ret; + } + + return 0; +} + +int PaxosLog :: ReadState(const int iGroupIdx, const uint64_t llInstanceID, AcceptorStateData & oState) +{ + const int m_iMyGroupIdx = iGroupIdx; + + string sBuffer; + int ret = m_poLogStorage->Get(iGroupIdx, llInstanceID, sBuffer); + if (ret != 0 && ret != 1) + { + PLG1Err("DB.Get fail, groupidx %d ret %d", iGroupIdx, ret); + return ret; + } + else if (ret == 1) + { + PLG1Imp("DB.Get not found, groupidx %d", iGroupIdx); + return 1; + } + + bool bSucc = oState.ParseFromArray(sBuffer.data(), sBuffer.size()); + if (!bSucc) + { + PLG1Err("State.ParseFromArray fail, bufferlen %zu", sBuffer.size()); + return -1; + } + + return 0; +} + +int PaxosLog :: GetMaxInstanceIDFromLog(const int iGroupIdx, uint64_t & llInstanceID) +{ + const int m_iMyGroupIdx = iGroupIdx; + + int ret = m_poLogStorage->GetMaxInstanceID(iGroupIdx, llInstanceID); + if (ret != 0 && ret != 1) + { + PLG1Err("DB.GetMax fail, groupidx %d ret %d", iGroupIdx, ret); + } + else if (ret == 1) + { + PLG1Debug("MaxInstanceID not exist, groupidx %d", iGroupIdx); + } + else + { + PLG1Imp("OK, MaxInstanceID %llu groupidsx %d", llInstanceID, iGroupIdx); + } + + return ret; +} + +} + diff --git a/src/logstorage/paxos_log.h b/src/logstorage/paxos_log.h new file mode 100644 index 000000000..b4443f325 --- /dev/null +++ b/src/logstorage/paxos_log.h @@ -0,0 +1,53 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include +#include "phxpaxos/storage.h" +#include "paxos_msg.pb.h" + +namespace phxpaxos +{ + +class PaxosLog +{ +public: + PaxosLog(const LogStorage * poLogStorage); + ~PaxosLog(); + + int WriteLog(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID, const std::string & sValue); + + int ReadLog(const int iGroupIdx, const uint64_t llInstanceID, std::string & sValue); + + int GetMaxInstanceIDFromLog(const int iGroupIdx, uint64_t & llInstanceID); + + int WriteState(const WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID, const AcceptorStateData & oState); + + int ReadState(const int iGroupIdx, const uint64_t llInstanceID, AcceptorStateData & oState); + +private: + LogStorage * m_poLogStorage; +}; + +} diff --git a/src/logstorage/system_variables_store.cpp b/src/logstorage/system_variables_store.cpp new file mode 100644 index 000000000..df4f42acb --- /dev/null +++ b/src/logstorage/system_variables_store.cpp @@ -0,0 +1,87 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "system_variables_store.h" +#include "db.h" + +namespace phxpaxos +{ + +SystemVariablesStore :: SystemVariablesStore(const LogStorage * poLogStorage) : m_poLogStorage((LogStorage *)poLogStorage) +{ +} + +SystemVariablesStore :: ~SystemVariablesStore() +{ +} + +int SystemVariablesStore :: Write(const WriteOptions & oWriteOptions, const int iGroupIdx, const SystemVariables & oVariables) +{ + const int m_iMyGroupIdx = iGroupIdx; + + string sBuffer; + bool sSucc = oVariables.SerializeToString(&sBuffer); + if (!sSucc) + { + PLG1Err("Variables.Serialize fail"); + return -1; + } + + int ret = m_poLogStorage->SetSystemVariables(oWriteOptions, iGroupIdx, sBuffer); + if (ret != 0) + { + PLG1Err("DB.Put fail, groupidx %d bufferlen %zu ret %d", + iGroupIdx, sBuffer.size(), ret); + return ret; + } + + return 0; +} + +int SystemVariablesStore :: Read(const int iGroupIdx, SystemVariables & oVariables) +{ + const int m_iMyGroupIdx = iGroupIdx; + + string sBuffer; + int ret = m_poLogStorage->GetSystemVariables(iGroupIdx, sBuffer); + if (ret != 0 && ret != 1) + { + PLG1Err("DB.Get fail, groupidx %d ret %d", iGroupIdx, ret); + return ret; + } + else if (ret == 1) + { + PLG1Imp("DB.Get not found, groupidx %d", iGroupIdx); + return 1; + } + + bool bSucc = oVariables.ParseFromArray(sBuffer.data(), sBuffer.size()); + if (!bSucc) + { + PLG1Err("Variables.ParseFromArray fail, bufferlen %zu", sBuffer.size()); + return -1; + } + + return 0; +} + +} + diff --git a/src/logstorage/system_variables_store.h b/src/logstorage/system_variables_store.h new file mode 100644 index 000000000..95afb1b31 --- /dev/null +++ b/src/logstorage/system_variables_store.h @@ -0,0 +1,47 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include +#include "phxpaxos/storage.h" +#include "paxos_msg.pb.h" + +namespace phxpaxos +{ + +class SystemVariablesStore +{ +public: + SystemVariablesStore(const LogStorage * poLogStorage); + ~SystemVariablesStore(); + + int Write(const WriteOptions & oWriteOptions, const int iGroupIdx, const SystemVariables & oVariables); + + int Read(const int iGroupIdx, SystemVariables & oVariables); + +private: + LogStorage * m_poLogStorage; +}; + +} diff --git a/src/master/Makefile.define b/src/master/Makefile.define new file mode 100644 index 000000000..560533290 --- /dev/null +++ b/src/master/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libmaster.a + +MASTER_OBJ=master_sm.pb.o master_sm.o master_damon.o master_variables_store.o + +MASTER_LIB=master src/utils:utils src/comm:comm src/config:config src/logstorage:logstorage + +MASTER_SYS_LIB= + +MASTER_INCS=$(SRC_BASE_PATH)/src/master + +MASTER_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/master/master_damon.cpp b/src/master/master_damon.cpp new file mode 100644 index 000000000..5870cc478 --- /dev/null +++ b/src/master/master_damon.cpp @@ -0,0 +1,163 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "master_damon.h" +#include "comm_include.h" +#include "commdef.h" + +namespace phxpaxos +{ + +MasterDamon :: MasterDamon(const Node * poPaxosNode, const int iGroupIdx, const LogStorage * poLogStorage) + : m_oDefaultMasterSM(poLogStorage, poPaxosNode->GetMyNodeID(), iGroupIdx) +{ + m_iLeaseTime = 10000; + + m_poPaxosNode = (Node *)poPaxosNode; + m_iMyGroupIdx = iGroupIdx; + + m_bIsEnd = false; + m_bIsStarted = false; + + m_bNeedDropMaster = false; +} + +MasterDamon :: ~MasterDamon() +{ +} + +int MasterDamon :: Init() +{ + return m_oDefaultMasterSM.Init(); +} + +void MasterDamon :: SetLeaseTime(const int iLeaseTimeMs) +{ + if (iLeaseTimeMs < 1000) + { + return; + } + + m_iLeaseTime = iLeaseTimeMs; +} + +void MasterDamon :: DropMaster() +{ + m_bNeedDropMaster = true; +} + +void MasterDamon :: StopMaster() +{ + if (m_bIsStarted) + { + m_bIsEnd = true; + join(); + } +} + +void MasterDamon :: RunMaster() +{ + start(); +} + +void MasterDamon :: run() +{ + m_bIsStarted = true; + + while(true) + { + if (m_bIsEnd) + { + return; + } + + int iLeaseTime = m_iLeaseTime; + + uint64_t llBeginTime = Time::GetTimestampMS(); + + TryBeMaster(iLeaseTime); + + int iConitnueLeaseTimeout = (iLeaseTime - 100) / 3; + + if (m_bNeedDropMaster) + { + m_bNeedDropMaster = false; + iConitnueLeaseTimeout = iLeaseTime * 2; + PLG1Imp("Need drop master, this round wait time %dms", iConitnueLeaseTimeout); + } + + uint64_t llEndTime = Time::GetTimestampMS(); + int iRunTime = llEndTime > llBeginTime ? llEndTime - llBeginTime : 0; + int iNeedSleepTime = iConitnueLeaseTimeout > iRunTime ? iConitnueLeaseTimeout - iRunTime : 0; + + PLG1Imp("TryBeMaster, sleep time %dms", iNeedSleepTime); + Time::MsSleep(iNeedSleepTime); + } +} + +void MasterDamon :: TryBeMaster(const int iLeaseTime) +{ + nodeid_t iMasterNodeID = nullnode; + uint64_t llMasterVersion = 0; + + //step 1 check exist master and get version + m_oDefaultMasterSM.SafeGetMaster(iMasterNodeID, llMasterVersion); + + if (iMasterNodeID != nullnode && (iMasterNodeID != m_poPaxosNode->GetMyNodeID())) + { + PLG1Imp("Ohter as master, can't try be master, masterid %lu myid %lu", + iMasterNodeID, m_poPaxosNode->GetMyNodeID()); + return; + } + + //step 2 try be master + std::string sPaxosValue; + if (!MasterStateMachine::MakeOpValue( + m_poPaxosNode->GetMyNodeID(), + llMasterVersion, + iLeaseTime, + MasterOperatorType_Complete, + sPaxosValue)) + { + PLG1Err("Make paxos value fail"); + return; + } + + const int iMasterLeaseTimeout = iLeaseTime - 100; + + uint64_t llAbsMasterTimeout = Time::GetTimestampMS() + iMasterLeaseTimeout; + uint64_t llCommitInstanceID = 0; + + SMCtx oCtx; + oCtx.m_iSMID = MASTER_V_SMID; + oCtx.m_pCtx = (void *)&llAbsMasterTimeout; + + m_poPaxosNode->Propose(m_iMyGroupIdx, sPaxosValue, llCommitInstanceID, &oCtx); +} + +MasterStateMachine * MasterDamon :: GetMasterSM() +{ + return &m_oDefaultMasterSM; +} + + +} + diff --git a/src/master/master_damon.h b/src/master/master_damon.h new file mode 100644 index 000000000..6b09b0b78 --- /dev/null +++ b/src/master/master_damon.h @@ -0,0 +1,71 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "commdef.h" +#include "utils_include.h" +#include "phxpaxos/node.h" +#include "master_sm.h" + +namespace phxpaxos +{ + +class MasterDamon : public Thread +{ +public: + MasterDamon(const Node * poPaxosNode, const int iGroupIdx, const LogStorage * poLogStorage); + ~MasterDamon(); + + void RunMaster(); + + void StopMaster(); + + int Init(); + + void run(); + + void SetLeaseTime(const int iLeaseTimeMs); + + void TryBeMaster(const int iLeaseTime); + + void DropMaster(); + +public: + MasterStateMachine * GetMasterSM(); + +private: + Node * m_poPaxosNode; + + MasterStateMachine m_oDefaultMasterSM; + +private: + int m_iLeaseTime; + + bool m_bIsEnd; + bool m_bIsStarted; + + int m_iMyGroupIdx; + + bool m_bNeedDropMaster; +}; + +} diff --git a/src/master/master_sm.cpp b/src/master/master_sm.cpp new file mode 100644 index 000000000..296bceef2 --- /dev/null +++ b/src/master/master_sm.cpp @@ -0,0 +1,315 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "master_sm.h" +#include "master_sm.pb.h" +#include +#include "commdef.h" +#include "comm_include.h" + +namespace phxpaxos +{ + +MasterStateMachine :: MasterStateMachine(const LogStorage * poLogStorage, const nodeid_t iMyNodeID, const int iGroupIdx) + : m_oMVStore(poLogStorage) +{ + m_iMyGroupIdx = iGroupIdx; + m_iMyNodeID = iMyNodeID; + + m_iMasterNodeID = nullnode; + m_llMasterVersion = (uint64_t)-1; + m_iLeaseTime = 0; + m_llAbsExpireTime = 0; + +} + +MasterStateMachine :: ~MasterStateMachine() +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////// + +int MasterStateMachine :: Init() +{ + MasterVariables oVariables; + int ret = m_oMVStore.Read(m_iMyGroupIdx, oVariables); + if (ret != 0 && ret != 1) + { + PLG1Err("Master variables read from store fail, ret %d", ret); + return -1; + } + + if (ret == 1) + { + PLG1Imp("no master variables exist"); + } + else + { + m_llMasterVersion = oVariables.version(); + + if (oVariables.masternodeid() == m_iMyNodeID) + { + m_iMasterNodeID = nullnode; + m_llAbsExpireTime = 0; + } + else + { + m_iMasterNodeID = oVariables.masternodeid(); + m_llAbsExpireTime = Time::GetTimestampMS() + oVariables.leasetime(); + } + } + + PLG1Head("OK, master nodeid %lu version %lu expiretime %u", + m_iMasterNodeID, m_llMasterVersion, m_llAbsExpireTime); + + return 0; +} + +int MasterStateMachine :: UpdateMasterToStore(const nodeid_t llMasterNodeID, const uint64_t llVersion, const uint32_t iLeaseTime) +{ + MasterVariables oVariables; + oVariables.set_masternodeid(llMasterNodeID); + oVariables.set_version(llVersion); + oVariables.set_leasetime(iLeaseTime); + + WriteOptions oWriteOptions; + oWriteOptions.bSync = false; + + return m_oMVStore.Write(oWriteOptions, m_iMyGroupIdx, oVariables); +} + +int MasterStateMachine :: LearnMaster( + const uint64_t llInstanceID, + const MasterOperator & oMasterOper, + const uint64_t llAbsMasterTimeout) +{ + ScopedLock oLockGuard(m_oMutex); + + if (oMasterOper.version() != m_llMasterVersion) + { + PLG1Err("version conflit, op version %lu now master version %lu", + oMasterOper.version(), m_llMasterVersion); + return 0; + } + + int ret = UpdateMasterToStore(oMasterOper.nodeid(), llInstanceID, oMasterOper.timeout()); + if (ret != 0) + { + PLG1Err("UpdateMasterToStore fail, ret %d", ret); + return -1; + } + + m_iMasterNodeID = oMasterOper.nodeid(); + if (m_iMasterNodeID == m_iMyNodeID) + { + //self be master + //use local abstimeout + m_llAbsExpireTime = llAbsMasterTimeout; + + PLG1Head("Be master success, absexpiretime %lu", m_llAbsExpireTime); + } + else + { + //other be master + //use new start timeout + m_llAbsExpireTime = Time::GetTimestampMS() + oMasterOper.timeout(); + + PLG1Head("Ohter be master, absexpiretime %lu", m_llAbsExpireTime); + } + + m_iLeaseTime = oMasterOper.timeout(); + m_llMasterVersion = llInstanceID; + + PLG1Imp("OK, masternodeid %lu version %lu abstimeout %lu", + m_iMasterNodeID, m_llMasterVersion, m_llAbsExpireTime); + + return 0; +} + +void MasterStateMachine :: SafeGetMaster(nodeid_t & iMasterNodeID, uint64_t & llMasterVersion) +{ + ScopedLock oLockGuard(m_oMutex); + + if (Time::GetTimestampMS() >= m_llAbsExpireTime) + { + iMasterNodeID = nullnode; + } + else + { + iMasterNodeID = m_iMasterNodeID; + } + + llMasterVersion = m_llMasterVersion; +} + +const nodeid_t MasterStateMachine :: GetMaster() const +{ + if (Time::GetTimestampMS() >= m_llAbsExpireTime) + { + return nullnode; + } + + return m_iMasterNodeID; +} + +const bool MasterStateMachine :: IsIMMaster() const +{ + nodeid_t iMasterNodeID = GetMaster(); + return iMasterNodeID == m_iMyNodeID; +} + +//////////////////////////////////////////////////////////////////////////////////////////// + +bool MasterStateMachine :: Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sValue, SMCtx * poSMCtx) +{ + MasterOperator oMasterOper; + bool bSucc = oMasterOper.ParseFromArray(sValue.data(), sValue.size()); + if (!bSucc) + { + PLG1Err("oMasterOper data wrong"); + //wrong oper data, just skip, so return true + return true; + } + + if (oMasterOper.operator_() == MasterOperatorType_Complete) + { + uint64_t * pAbsMasterTimeout = nullptr; + if (poSMCtx != nullptr && poSMCtx->m_pCtx != nullptr) + { + pAbsMasterTimeout = (uint64_t *)poSMCtx->m_pCtx; + } + + uint64_t llAbsMasterTimeout = pAbsMasterTimeout != nullptr ? *pAbsMasterTimeout : 0; + + PLG1Imp("absmaster timeout %lu", llAbsMasterTimeout); + + int ret = LearnMaster(llInstanceID, oMasterOper, llAbsMasterTimeout); + if (ret != 0) + { + return false; + } + } + else + { + PLG1Err("unknown op %u", oMasterOper.operator_()); + //wrong op, just skip, so return true; + return true; + } + + return true; +} + +//////////////////////////////////////////////////// + +bool MasterStateMachine :: MakeOpValue( + const nodeid_t iNodeID, + const uint64_t llVersion, + const int iTimeout, + const MasterOperatorType iOp, + std::string & sPaxosValue) +{ + MasterOperator oMasterOper; + oMasterOper.set_nodeid(iNodeID); + oMasterOper.set_version(llVersion); + oMasterOper.set_timeout(iTimeout); + oMasterOper.set_operator_(iOp); + oMasterOper.set_sid(OtherUtils::FastRand()); + + return oMasterOper.SerializeToString(&sPaxosValue); +} + +//////////////////////////////////////////////////////////// + +int MasterStateMachine :: GetCheckpointBuffer(std::string & sCPBuffer) +{ + if (m_llMasterVersion == (uint64_t)-1) + { + return 0; + } + + MasterVariables oVariables; + oVariables.set_masternodeid(m_iMasterNodeID); + oVariables.set_version(m_llMasterVersion); + oVariables.set_leasetime(m_iLeaseTime); + + bool sSucc = oVariables.SerializeToString(&sCPBuffer); + if (!sSucc) + { + PLG1Err("Variables.Serialize fail"); + return -1; + } + + return 0; +} + +int MasterStateMachine :: UpdateByCheckpoint(const std::string & sCPBuffer, bool & bChange) +{ + if (sCPBuffer.size() == 0) + { + return 0; + } + + MasterVariables oVariables; + bool bSucc = oVariables.ParseFromArray(sCPBuffer.data(), sCPBuffer.size()); + if (!bSucc) + { + PLG1Err("Variables.ParseFromArray fail, bufferlen %zu", sCPBuffer.size()); + return -1; + } + + if (oVariables.version() <= m_llMasterVersion + && m_llMasterVersion != (uint64_t)-1) + { + PLG1Imp("lag checkpoint, no need update, cp.version %lu now.version %lu", + oVariables.version(), m_llMasterVersion); + return 0; + } + + + int ret = UpdateMasterToStore(oVariables.masternodeid(), oVariables.version(), oVariables.leasetime()); + if (ret != 0) + { + return -1; + } + + PLG1Head("ok, cp.version %lu cp.masternodeid %lu old.version %lu old.masternodeid %lu", + oVariables.version(), oVariables.masternodeid(), + m_llMasterVersion, m_iMasterNodeID); + + m_llMasterVersion = oVariables.version(); + + if (oVariables.masternodeid() == m_iMyNodeID) + { + m_iMasterNodeID = nullnode; + m_llAbsExpireTime = 0; + } + else + { + m_iMasterNodeID = oVariables.masternodeid(); + m_llAbsExpireTime = Time::GetTimestampMS() + oVariables.leasetime(); + } + + return 0; +} + +} + diff --git a/src/master/master_sm.h b/src/master/master_sm.h new file mode 100644 index 000000000..fc6326e5c --- /dev/null +++ b/src/master/master_sm.h @@ -0,0 +1,129 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/sm.h" +#include "commdef.h" +#include "phxpaxos/def.h" +#include "config_include.h" +#include "master_sm.pb.h" +#include "master_sm.h" +#include "master_variables_store.h" +#include "utils_include.h" + +namespace phxpaxos +{ + +enum MasterOperatorType +{ + MasterOperatorType_Complete = 1, +}; + +class MasterStateMachine : public InsideSM +{ +public: + MasterStateMachine(const LogStorage * poLogStorage, const nodeid_t iMyNodeID, const int iGroupIdx); + ~MasterStateMachine(); + + bool Execute(const int iGroupIdx, const uint64_t llInstanceID, const std::string & sValue, SMCtx * poSMCtx); + + const int SMID() const {return MASTER_V_SMID;} + + bool ExecuteForCheckpoint(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue) + { + return true; + } + + const uint64_t GetCheckpointInstanceID(const int iGroupIdx) const + { + return m_llMasterVersion; + } + +public: + int GetCheckpointState(const int iGroupIdx, std::string & sDirPath, + std::vector & vecFileList) + { + return 0; + } + + int LoadCheckpointState(const int iGroupIdx, const std::string & sCheckpointTmpFileDirPath, + const std::vector & vecFileList, const uint64_t llCheckpointInstanceID) + { + return 0; + } + + int LockCheckpointState() + { + return 0; + } + + void UnLockCheckpointState() + { + } + +public: + int Init(); + + int LearnMaster( + const uint64_t llInstanceID, + const MasterOperator & oMasterOper, + const uint64_t llAbsMasterTimeout = 0); + + const nodeid_t GetMaster() const; + + const bool IsIMMaster() const; + +public: + int UpdateMasterToStore(const nodeid_t llMasterNodeID, const uint64_t llVersion, const uint32_t iLeaseTime); + + void SafeGetMaster(nodeid_t & iMasterNodeID, uint64_t & llMasterVersion); + +public: + static bool MakeOpValue( + const nodeid_t iNodeID, + const uint64_t llVersion, + const int iTimeout, + const MasterOperatorType iOp, + std::string & sPaxosValue); + +public: + int GetCheckpointBuffer(std::string & sCPBuffer); + + int UpdateByCheckpoint(const std::string & sCPBuffer, bool & bChange); + +private: + int m_iMyGroupIdx; + nodeid_t m_iMyNodeID; + +private: + MasterVariablesStore m_oMVStore; + + nodeid_t m_iMasterNodeID; + uint64_t m_llMasterVersion; + int m_iLeaseTime; + uint64_t m_llAbsExpireTime; + + Mutex m_oMutex; +}; + +} diff --git a/src/master/master_sm.pb.cc b/src/master/master_sm.pb.cc new file mode 100644 index 000000000..127734490 --- /dev/null +++ b/src/master/master_sm.pb.cc @@ -0,0 +1,673 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: master_sm.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "master_sm.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace phxpaxos { + +namespace { + +const ::google::protobuf::Descriptor* MasterOperator_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + MasterOperator_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_master_5fsm_2eproto() { + protobuf_AddDesc_master_5fsm_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "master_sm.proto"); + GOOGLE_CHECK(file != NULL); + MasterOperator_descriptor_ = file->message_type(0); + static const int MasterOperator_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterOperator, nodeid_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterOperator, version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterOperator, timeout_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterOperator, operator__), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterOperator, sid_), + }; + MasterOperator_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + MasterOperator_descriptor_, + MasterOperator::default_instance_, + MasterOperator_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterOperator, _has_bits_[0]), + -1, + -1, + sizeof(MasterOperator), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MasterOperator, _internal_metadata_), + -1); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_master_5fsm_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + MasterOperator_descriptor_, &MasterOperator::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_master_5fsm_2eproto() { + delete MasterOperator::default_instance_; + delete MasterOperator_reflection_; +} + +void protobuf_AddDesc_master_5fsm_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\017master_sm.proto\022\010phxpaxos\"a\n\016MasterOpe" + "rator\022\016\n\006nodeid\030\001 \002(\004\022\017\n\007version\030\002 \002(\004\022\017" + "\n\007timeout\030\003 \002(\005\022\020\n\010operator\030\004 \002(\r\022\013\n\003sid" + "\030\005 \002(\r", 126); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "master_sm.proto", &protobuf_RegisterTypes); + MasterOperator::default_instance_ = new MasterOperator(); + MasterOperator::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_master_5fsm_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_master_5fsm_2eproto { + StaticDescriptorInitializer_master_5fsm_2eproto() { + protobuf_AddDesc_master_5fsm_2eproto(); + } +} static_descriptor_initializer_master_5fsm_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int MasterOperator::kNodeidFieldNumber; +const int MasterOperator::kVersionFieldNumber; +const int MasterOperator::kTimeoutFieldNumber; +const int MasterOperator::kOperatorFieldNumber; +const int MasterOperator::kSidFieldNumber; +#endif // !_MSC_VER + +MasterOperator::MasterOperator() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:phxpaxos.MasterOperator) +} + +void MasterOperator::InitAsDefaultInstance() { +} + +MasterOperator::MasterOperator(const MasterOperator& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:phxpaxos.MasterOperator) +} + +void MasterOperator::SharedCtor() { + _cached_size_ = 0; + nodeid_ = GOOGLE_ULONGLONG(0); + version_ = GOOGLE_ULONGLONG(0); + timeout_ = 0; + operator__ = 0u; + sid_ = 0u; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +MasterOperator::~MasterOperator() { + // @@protoc_insertion_point(destructor:phxpaxos.MasterOperator) + SharedDtor(); +} + +void MasterOperator::SharedDtor() { + if (this != default_instance_) { + } +} + +void MasterOperator::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* MasterOperator::descriptor() { + protobuf_AssignDescriptorsOnce(); + return MasterOperator_descriptor_; +} + +const MasterOperator& MasterOperator::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_master_5fsm_2eproto(); + return *default_instance_; +} + +MasterOperator* MasterOperator::default_instance_ = NULL; + +MasterOperator* MasterOperator::New(::google::protobuf::Arena* arena) const { + MasterOperator* n = new MasterOperator; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void MasterOperator::Clear() { +#define ZR_HELPER_(f) reinterpret_cast(\ + &reinterpret_cast(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + if (_has_bits_[0 / 32] & 31u) { + ZR_(nodeid_, sid_); + } + +#undef ZR_HELPER_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool MasterOperator::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:phxpaxos.MasterOperator) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required uint64 nodeid = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &nodeid_))); + set_has_nodeid(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_version; + break; + } + + // required uint64 version = 2; + case 2: { + if (tag == 16) { + parse_version: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &version_))); + set_has_version(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_timeout; + break; + } + + // required int32 timeout = 3; + case 3: { + if (tag == 24) { + parse_timeout: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &timeout_))); + set_has_timeout(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_operator; + break; + } + + // required uint32 operator = 4; + case 4: { + if (tag == 32) { + parse_operator: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &operator__))); + set_has_operator_(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_sid; + break; + } + + // required uint32 sid = 5; + case 5: { + if (tag == 40) { + parse_sid: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &sid_))); + set_has_sid(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:phxpaxos.MasterOperator) + return true; +failure: + // @@protoc_insertion_point(parse_failure:phxpaxos.MasterOperator) + return false; +#undef DO_ +} + +void MasterOperator::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:phxpaxos.MasterOperator) + // required uint64 nodeid = 1; + if (has_nodeid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->nodeid(), output); + } + + // required uint64 version = 2; + if (has_version()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->version(), output); + } + + // required int32 timeout = 3; + if (has_timeout()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->timeout(), output); + } + + // required uint32 operator = 4; + if (has_operator_()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->operator_(), output); + } + + // required uint32 sid = 5; + if (has_sid()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->sid(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:phxpaxos.MasterOperator) +} + +::google::protobuf::uint8* MasterOperator::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:phxpaxos.MasterOperator) + // required uint64 nodeid = 1; + if (has_nodeid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->nodeid(), target); + } + + // required uint64 version = 2; + if (has_version()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->version(), target); + } + + // required int32 timeout = 3; + if (has_timeout()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->timeout(), target); + } + + // required uint32 operator = 4; + if (has_operator_()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->operator_(), target); + } + + // required uint32 sid = 5; + if (has_sid()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->sid(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:phxpaxos.MasterOperator) + return target; +} + +int MasterOperator::RequiredFieldsByteSizeFallback() const { + int total_size = 0; + + if (has_nodeid()) { + // required uint64 nodeid = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->nodeid()); + } + + if (has_version()) { + // required uint64 version = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->version()); + } + + if (has_timeout()) { + // required int32 timeout = 3; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->timeout()); + } + + if (has_operator_()) { + // required uint32 operator = 4; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->operator_()); + } + + if (has_sid()) { + // required uint32 sid = 5; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->sid()); + } + + return total_size; +} +int MasterOperator::ByteSize() const { + int total_size = 0; + + if (((_has_bits_[0] & 0x0000001f) ^ 0x0000001f) == 0) { // All required fields are present. + // required uint64 nodeid = 1; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->nodeid()); + + // required uint64 version = 2; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->version()); + + // required int32 timeout = 3; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->timeout()); + + // required uint32 operator = 4; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->operator_()); + + // required uint32 sid = 5; + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->sid()); + + } else { + total_size += RequiredFieldsByteSizeFallback(); + } + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void MasterOperator::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const MasterOperator* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void MasterOperator::MergeFrom(const MasterOperator& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_nodeid()) { + set_nodeid(from.nodeid()); + } + if (from.has_version()) { + set_version(from.version()); + } + if (from.has_timeout()) { + set_timeout(from.timeout()); + } + if (from.has_operator_()) { + set_operator_(from.operator_()); + } + if (from.has_sid()) { + set_sid(from.sid()); + } + } + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void MasterOperator::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void MasterOperator::CopyFrom(const MasterOperator& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MasterOperator::IsInitialized() const { + if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false; + + return true; +} + +void MasterOperator::Swap(MasterOperator* other) { + if (other == this) return; + InternalSwap(other); +} +void MasterOperator::InternalSwap(MasterOperator* other) { + std::swap(nodeid_, other->nodeid_); + std::swap(version_, other->version_); + std::swap(timeout_, other->timeout_); + std::swap(operator__, other->operator__); + std::swap(sid_, other->sid_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata MasterOperator::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = MasterOperator_descriptor_; + metadata.reflection = MasterOperator_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// MasterOperator + +// required uint64 nodeid = 1; +bool MasterOperator::has_nodeid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void MasterOperator::set_has_nodeid() { + _has_bits_[0] |= 0x00000001u; +} +void MasterOperator::clear_has_nodeid() { + _has_bits_[0] &= ~0x00000001u; +} +void MasterOperator::clear_nodeid() { + nodeid_ = GOOGLE_ULONGLONG(0); + clear_has_nodeid(); +} + ::google::protobuf::uint64 MasterOperator::nodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterOperator.nodeid) + return nodeid_; +} + void MasterOperator::set_nodeid(::google::protobuf::uint64 value) { + set_has_nodeid(); + nodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterOperator.nodeid) +} + +// required uint64 version = 2; +bool MasterOperator::has_version() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void MasterOperator::set_has_version() { + _has_bits_[0] |= 0x00000002u; +} +void MasterOperator::clear_has_version() { + _has_bits_[0] &= ~0x00000002u; +} +void MasterOperator::clear_version() { + version_ = GOOGLE_ULONGLONG(0); + clear_has_version(); +} + ::google::protobuf::uint64 MasterOperator::version() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterOperator.version) + return version_; +} + void MasterOperator::set_version(::google::protobuf::uint64 value) { + set_has_version(); + version_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterOperator.version) +} + +// required int32 timeout = 3; +bool MasterOperator::has_timeout() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +void MasterOperator::set_has_timeout() { + _has_bits_[0] |= 0x00000004u; +} +void MasterOperator::clear_has_timeout() { + _has_bits_[0] &= ~0x00000004u; +} +void MasterOperator::clear_timeout() { + timeout_ = 0; + clear_has_timeout(); +} + ::google::protobuf::int32 MasterOperator::timeout() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterOperator.timeout) + return timeout_; +} + void MasterOperator::set_timeout(::google::protobuf::int32 value) { + set_has_timeout(); + timeout_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterOperator.timeout) +} + +// required uint32 operator = 4; +bool MasterOperator::has_operator_() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +void MasterOperator::set_has_operator_() { + _has_bits_[0] |= 0x00000008u; +} +void MasterOperator::clear_has_operator_() { + _has_bits_[0] &= ~0x00000008u; +} +void MasterOperator::clear_operator_() { + operator__ = 0u; + clear_has_operator_(); +} + ::google::protobuf::uint32 MasterOperator::operator_() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterOperator.operator) + return operator__; +} + void MasterOperator::set_operator_(::google::protobuf::uint32 value) { + set_has_operator_(); + operator__ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterOperator.operator) +} + +// required uint32 sid = 5; +bool MasterOperator::has_sid() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +void MasterOperator::set_has_sid() { + _has_bits_[0] |= 0x00000010u; +} +void MasterOperator::clear_has_sid() { + _has_bits_[0] &= ~0x00000010u; +} +void MasterOperator::clear_sid() { + sid_ = 0u; + clear_has_sid(); +} + ::google::protobuf::uint32 MasterOperator::sid() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterOperator.sid) + return sid_; +} + void MasterOperator::set_sid(::google::protobuf::uint32 value) { + set_has_sid(); + sid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterOperator.sid) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace phxpaxos + +// @@protoc_insertion_point(global_scope) diff --git a/src/master/master_sm.pb.h b/src/master/master_sm.pb.h new file mode 100644 index 000000000..afc3a0993 --- /dev/null +++ b/src/master/master_sm.pb.h @@ -0,0 +1,309 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: master_sm.proto + +#ifndef PROTOBUF_master_5fsm_2eproto__INCLUDED +#define PROTOBUF_master_5fsm_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace phxpaxos { + +// Internal implementation detail -- do not call these. +void protobuf_AddDesc_master_5fsm_2eproto(); +void protobuf_AssignDesc_master_5fsm_2eproto(); +void protobuf_ShutdownFile_master_5fsm_2eproto(); + +class MasterOperator; + +// =================================================================== + +class MasterOperator : public ::google::protobuf::Message { + public: + MasterOperator(); + virtual ~MasterOperator(); + + MasterOperator(const MasterOperator& from); + + inline MasterOperator& operator=(const MasterOperator& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MasterOperator& default_instance(); + + void Swap(MasterOperator* other); + + // implements Message ---------------------------------------------- + + inline MasterOperator* New() const { return New(NULL); } + + MasterOperator* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const MasterOperator& from); + void MergeFrom(const MasterOperator& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(MasterOperator* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required uint64 nodeid = 1; + bool has_nodeid() const; + void clear_nodeid(); + static const int kNodeidFieldNumber = 1; + ::google::protobuf::uint64 nodeid() const; + void set_nodeid(::google::protobuf::uint64 value); + + // required uint64 version = 2; + bool has_version() const; + void clear_version(); + static const int kVersionFieldNumber = 2; + ::google::protobuf::uint64 version() const; + void set_version(::google::protobuf::uint64 value); + + // required int32 timeout = 3; + bool has_timeout() const; + void clear_timeout(); + static const int kTimeoutFieldNumber = 3; + ::google::protobuf::int32 timeout() const; + void set_timeout(::google::protobuf::int32 value); + + // required uint32 operator = 4; + bool has_operator_() const; + void clear_operator_(); + static const int kOperatorFieldNumber = 4; + ::google::protobuf::uint32 operator_() const; + void set_operator_(::google::protobuf::uint32 value); + + // required uint32 sid = 5; + bool has_sid() const; + void clear_sid(); + static const int kSidFieldNumber = 5; + ::google::protobuf::uint32 sid() const; + void set_sid(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:phxpaxos.MasterOperator) + private: + inline void set_has_nodeid(); + inline void clear_has_nodeid(); + inline void set_has_version(); + inline void clear_has_version(); + inline void set_has_timeout(); + inline void clear_has_timeout(); + inline void set_has_operator_(); + inline void clear_has_operator_(); + inline void set_has_sid(); + inline void clear_has_sid(); + + // helper for ByteSize() + int RequiredFieldsByteSizeFallback() const; + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::uint64 nodeid_; + ::google::protobuf::uint64 version_; + ::google::protobuf::int32 timeout_; + ::google::protobuf::uint32 operator__; + ::google::protobuf::uint32 sid_; + friend void protobuf_AddDesc_master_5fsm_2eproto(); + friend void protobuf_AssignDesc_master_5fsm_2eproto(); + friend void protobuf_ShutdownFile_master_5fsm_2eproto(); + + void InitAsDefaultInstance(); + static MasterOperator* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// MasterOperator + +// required uint64 nodeid = 1; +inline bool MasterOperator::has_nodeid() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MasterOperator::set_has_nodeid() { + _has_bits_[0] |= 0x00000001u; +} +inline void MasterOperator::clear_has_nodeid() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MasterOperator::clear_nodeid() { + nodeid_ = GOOGLE_ULONGLONG(0); + clear_has_nodeid(); +} +inline ::google::protobuf::uint64 MasterOperator::nodeid() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterOperator.nodeid) + return nodeid_; +} +inline void MasterOperator::set_nodeid(::google::protobuf::uint64 value) { + set_has_nodeid(); + nodeid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterOperator.nodeid) +} + +// required uint64 version = 2; +inline bool MasterOperator::has_version() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MasterOperator::set_has_version() { + _has_bits_[0] |= 0x00000002u; +} +inline void MasterOperator::clear_has_version() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MasterOperator::clear_version() { + version_ = GOOGLE_ULONGLONG(0); + clear_has_version(); +} +inline ::google::protobuf::uint64 MasterOperator::version() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterOperator.version) + return version_; +} +inline void MasterOperator::set_version(::google::protobuf::uint64 value) { + set_has_version(); + version_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterOperator.version) +} + +// required int32 timeout = 3; +inline bool MasterOperator::has_timeout() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MasterOperator::set_has_timeout() { + _has_bits_[0] |= 0x00000004u; +} +inline void MasterOperator::clear_has_timeout() { + _has_bits_[0] &= ~0x00000004u; +} +inline void MasterOperator::clear_timeout() { + timeout_ = 0; + clear_has_timeout(); +} +inline ::google::protobuf::int32 MasterOperator::timeout() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterOperator.timeout) + return timeout_; +} +inline void MasterOperator::set_timeout(::google::protobuf::int32 value) { + set_has_timeout(); + timeout_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterOperator.timeout) +} + +// required uint32 operator = 4; +inline bool MasterOperator::has_operator_() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MasterOperator::set_has_operator_() { + _has_bits_[0] |= 0x00000008u; +} +inline void MasterOperator::clear_has_operator_() { + _has_bits_[0] &= ~0x00000008u; +} +inline void MasterOperator::clear_operator_() { + operator__ = 0u; + clear_has_operator_(); +} +inline ::google::protobuf::uint32 MasterOperator::operator_() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterOperator.operator) + return operator__; +} +inline void MasterOperator::set_operator_(::google::protobuf::uint32 value) { + set_has_operator_(); + operator__ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterOperator.operator) +} + +// required uint32 sid = 5; +inline bool MasterOperator::has_sid() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void MasterOperator::set_has_sid() { + _has_bits_[0] |= 0x00000010u; +} +inline void MasterOperator::clear_has_sid() { + _has_bits_[0] &= ~0x00000010u; +} +inline void MasterOperator::clear_sid() { + sid_ = 0u; + clear_has_sid(); +} +inline ::google::protobuf::uint32 MasterOperator::sid() const { + // @@protoc_insertion_point(field_get:phxpaxos.MasterOperator.sid) + return sid_; +} +inline void MasterOperator::set_sid(::google::protobuf::uint32 value) { + set_has_sid(); + sid_ = value; + // @@protoc_insertion_point(field_set:phxpaxos.MasterOperator.sid) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace phxpaxos + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_master_5fsm_2eproto__INCLUDED diff --git a/src/master/master_sm.proto b/src/master/master_sm.proto new file mode 100644 index 000000000..05929efc4 --- /dev/null +++ b/src/master/master_sm.proto @@ -0,0 +1,12 @@ +// Copyright (c) 2016 The Paxoslib Authors(lynncui@tencent). All rights reserved. +syntax = "proto2"; +package phxpaxos; + +message MasterOperator +{ + required uint64 nodeid = 1; + required uint64 version = 2; + required int32 timeout = 3; + required uint32 operator = 4; + required uint32 sid = 5; +}; diff --git a/src/master/master_variables_store.cpp b/src/master/master_variables_store.cpp new file mode 100644 index 000000000..f0a35e03a --- /dev/null +++ b/src/master/master_variables_store.cpp @@ -0,0 +1,87 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "master_variables_store.h" +#include "db.h" + +namespace phxpaxos +{ + +MasterVariablesStore :: MasterVariablesStore(const LogStorage * poLogStorage) : m_poLogStorage((LogStorage *)poLogStorage) +{ +} + +MasterVariablesStore :: ~MasterVariablesStore() +{ +} + +int MasterVariablesStore :: Write(const WriteOptions & oWriteOptions, const int iGroupIdx, const MasterVariables & oVariables) +{ + const int m_iMyGroupIdx = iGroupIdx; + + string sBuffer; + bool sSucc = oVariables.SerializeToString(&sBuffer); + if (!sSucc) + { + PLG1Err("Variables.Serialize fail"); + return -1; + } + + int ret = m_poLogStorage->SetMasterVariables(oWriteOptions, iGroupIdx, sBuffer); + if (ret != 0) + { + PLG1Err("DB.Put fail, groupidx %d bufferlen %zu ret %d", + iGroupIdx, sBuffer.size(), ret); + return ret; + } + + return 0; +} + +int MasterVariablesStore :: Read(const int iGroupIdx, MasterVariables & oVariables) +{ + const int m_iMyGroupIdx = iGroupIdx; + + string sBuffer; + int ret = m_poLogStorage->GetMasterVariables(iGroupIdx, sBuffer); + if (ret != 0 && ret != 1) + { + PLG1Err("DB.Get fail, groupidx %d ret %d", iGroupIdx, ret); + return ret; + } + else if (ret == 1) + { + PLG1Imp("DB.Get not found, groupidx %d", iGroupIdx); + return 1; + } + + bool bSucc = oVariables.ParseFromArray(sBuffer.data(), sBuffer.size()); + if (!bSucc) + { + PLG1Err("Variables.ParseFromArray fail, bufferlen %zu", sBuffer.size()); + return -1; + } + + return 0; +} + +} + diff --git a/src/master/master_variables_store.h b/src/master/master_variables_store.h new file mode 100644 index 000000000..0f48da52b --- /dev/null +++ b/src/master/master_variables_store.h @@ -0,0 +1,47 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include +#include "phxpaxos/storage.h" +#include "paxos_msg.pb.h" + +namespace phxpaxos +{ + +class MasterVariablesStore +{ +public: + MasterVariablesStore(const LogStorage * poLogStorage); + ~MasterVariablesStore(); + + int Write(const WriteOptions & oWriteOptions, const int iGroupIdx, const MasterVariables & oVariables); + + int Read(const int iGroupIdx, MasterVariables & oVariables); + +private: + LogStorage * m_poLogStorage; +}; + +} diff --git a/src/node/Makefile.define b/src/node/Makefile.define new file mode 100644 index 000000000..f5b62dfc5 --- /dev/null +++ b/src/node/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libnode.a + +NODE_OBJ=group.o pnode.o node.o + +NODE_LIB=node src/comm:comm src/logstorage:logstorage src/communicate:communicate include:include src/algorithm:algorithm src/config:config src/master:master + +NODE_SYS_LIB= + +NODE_INCS=$(SRC_BASE_PATH)/src/node + +NODE_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/node/group.cpp b/src/node/group.cpp new file mode 100644 index 000000000..71dd27017 --- /dev/null +++ b/src/node/group.cpp @@ -0,0 +1,91 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "group.h" + +namespace phxpaxos +{ + + +Group :: Group(LogStorage * poLogStorage, + NetWork * poNetWork, + InsideSM * poMasterSM, + const int iGroupIdx, + const Options & oOptions) : + m_oCommunicate(&m_oConfig, oOptions.oMyNode.GetNodeID(), oOptions.iUDPMaxSize, poNetWork), + m_oConfig(poLogStorage, false, oOptions.oMyNode, oOptions.vecNodeInfoList, + oOptions.vecFollowerNodeInfoList, iGroupIdx, oOptions.iGroupCount, nullptr), + m_oInstance(&m_oConfig, poLogStorage, &m_oCommunicate, oOptions.bUseCheckpointReplayer) +{ + m_oConfig.SetMasterSM(poMasterSM); +} + +Group :: ~Group() +{ +} + +int Group :: Init() +{ + int ret = m_oConfig.Init(); + if (ret != 0) + { + return ret; + } + + //inside sm + AddStateMachine(m_oConfig.GetSystemVSM()); + AddStateMachine(m_oConfig.GetMasterSM()); + + return m_oInstance.Init(); +} + +Config * Group :: GetConfig() +{ + return &m_oConfig; +} + +Instance * Group :: GetInstance() +{ + return &m_oInstance; +} + +Committer * Group :: GetCommitter() +{ + return m_oInstance.GetCommitter(); +} + +Cleaner * Group :: GetCheckpointCleaner() +{ + return m_oInstance.GetCheckpointCleaner(); +} + +Replayer * Group :: GetCheckpointReplayer() +{ + return m_oInstance.GetCheckpointReplayer(); +} + +void Group :: AddStateMachine(StateMachine * poSM) +{ + m_oInstance.AddStateMachine(poSM); +} + +} + diff --git a/src/node/group.h b/src/node/group.h new file mode 100644 index 000000000..d9ee0cdfb --- /dev/null +++ b/src/node/group.h @@ -0,0 +1,66 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "comm_include.h" +#include "config_include.h" +#include "instance.h" +#include "cleaner.h" +#include "communicate.h" +#include "phxpaxos/options.h" +#include "phxpaxos/network.h" + +namespace phxpaxos +{ + +class Group +{ +public: + Group(LogStorage * poLogStorage, + NetWork * poNetWork, + InsideSM * poMasterSM, + const int iGroupIdx, + const Options & oOptions); + + ~Group(); + + int Init(); + + Config * GetConfig(); + + Instance * GetInstance(); + + Committer * GetCommitter(); + + Cleaner * GetCheckpointCleaner(); + + Replayer * GetCheckpointReplayer(); + + void AddStateMachine(StateMachine * poSM); + +private: + Communicate m_oCommunicate; + Config m_oConfig; + Instance m_oInstance; +}; + +} diff --git a/src/node/node.cpp b/src/node/node.cpp new file mode 100644 index 000000000..a377b849f --- /dev/null +++ b/src/node/node.cpp @@ -0,0 +1,64 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "phxpaxos/node.h" +#include "pnode.h" + +namespace phxpaxos +{ + +int Node :: RunNode(const Options & oOptions, Node *& poNode) +{ + if (oOptions.bIsLargeValueMode) + { + InsideOptions::Instance()->SetAsLargeBufferMode(); + } + + poNode = nullptr; + NetWork * poNetWork = nullptr; + + Breakpoint::m_poBreakpoint = nullptr; + BP->SetInstance(oOptions.poBreakpoint); + + PNode * poRealNode = new PNode(); + int ret = poRealNode->Init(oOptions, poNetWork); + if (ret != 0) + { + return ret; + } + + //step1 set node to network + //very important, let network on recieve callback can work. + poNetWork->m_poNode = poRealNode; + + //step2 run network. + //start recieve message from network, so all must init before this step. + //must be the last step. + poNetWork->RunNetWork(); + + + poNode = poRealNode; + + return 0; +} + +} + diff --git a/src/node/pnode.cpp b/src/node/pnode.cpp new file mode 100644 index 000000000..947634070 --- /dev/null +++ b/src/node/pnode.cpp @@ -0,0 +1,452 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "pnode.h" + +namespace phxpaxos +{ + +PNode :: PNode() + : m_iMyNodeID(nullnode) +{ +} + +PNode :: ~PNode() +{ + //1.step: must stop master(app) first. + for (auto & poMaster : m_vecMasterList) + { + poMaster->StopMaster(); + } + + //2.step: stop network. + m_oDefaultNetWork.StopNetWork(); + + //3.step: delete paxos instance. + for (auto & poGroup : m_vecGroupList) + { + delete poGroup; + } + + //4. step: delete master state machine. + for (auto & poMaster : m_vecMasterList) + { + delete poMaster; + } +} + +int PNode :: InitLogStorage(const Options & oOptions, LogStorage *& poLogStorage) +{ + if (oOptions.poLogStorage != nullptr) + { + poLogStorage = oOptions.poLogStorage; + PLImp("OK, use user logstorage"); + return 0; + } + + if (oOptions.sLogStoragePath.size() == 0) + { + PLErr("LogStorage Path is null"); + return -2; + } + + int ret = m_oDefaultLogStorage.Init(oOptions.sLogStoragePath, oOptions.iGroupCount); + if (ret != 0) + { + PLErr("Init default logstorage fail, logpath %s ret %d", + oOptions.sLogStoragePath.c_str(), ret); + return ret; + } + + poLogStorage = &m_oDefaultLogStorage; + + PLImp("OK, use default logstorage"); + + return 0; +} + +int PNode :: InitNetWork(const Options & oOptions, NetWork *& poNetWork) +{ + if (oOptions.poNetWork != nullptr) + { + poNetWork = oOptions.poNetWork; + PLImp("OK, use user network"); + return 0; + } + + int ret = m_oDefaultNetWork.Init(oOptions.oMyNode.GetIP(), oOptions.oMyNode.GetPort()); + if (ret != 0) + { + PLErr("init default network fail, listenip %s listenport %d ret %d", + oOptions.oMyNode.GetIP().c_str(), oOptions.oMyNode.GetPort(), ret); + return ret; + } + + poNetWork = &m_oDefaultNetWork; + + PLImp("OK, use default network"); + + return 0; +} + +int PNode :: CheckOptions(const Options & oOptions) +{ + //init logger + if (oOptions.pLogFunc != nullptr) + { + LOGGER->SetLogFunc(oOptions.pLogFunc); + } + else + { + LOGGER->InitLogger(oOptions.eLogLevel); + } + + if (oOptions.poLogStorage == nullptr && oOptions.sLogStoragePath.size() == 0) + { + PLErr("no logpath and logstorage is null"); + return -2; + } + + if (oOptions.iUDPMaxSize > 64 * 1024) + { + PLErr("udp max size %zu is too large", oOptions.iUDPMaxSize); + return -2; + } + + if (oOptions.iGroupCount > 300) + { + PLErr("group count %d is too large", oOptions.iGroupCount); + return -2; + } + + if (oOptions.iGroupCount < 0) + { + PLErr("group count %d is small than zero", oOptions.iGroupCount); + return -2; + } + + for (auto & oFollowerNodeInfo : oOptions.vecFollowerNodeInfoList) + { + if (oFollowerNodeInfo.oMyNode.GetNodeID() == oFollowerNodeInfo.oFollowNode.GetNodeID()) + { + PLErr("self node ip %s port %d equal to follow node", + oFollowerNodeInfo.oMyNode.GetIP().c_str(), oFollowerNodeInfo.oMyNode.GetPort()); + return -2; + } + } + + for (auto & oGroupSMInfo : oOptions.vecGroupSMInfoList) + { + if (oGroupSMInfo.iGroupIdx >= oOptions.iGroupCount) + { + PLErr("SM GroupIdx %d large than GroupCount %d", + oGroupSMInfo.iGroupIdx, oOptions.iGroupCount); + return -2; + } + } + + return 0; +} + +void PNode :: InitStateMachine(const Options & oOptions) +{ + for (auto & oGroupSMInfo : oOptions.vecGroupSMInfoList) + { + for (auto & poSM : oGroupSMInfo.vecSMList) + { + AddStateMachine(oGroupSMInfo.iGroupIdx, poSM); + } + + //check if need to run master. + if (oGroupSMInfo.bIsUseMaster) + { + if (!m_vecGroupList[oGroupSMInfo.iGroupIdx]->GetConfig()->IsIMFollower()) + { + m_vecMasterList[oGroupSMInfo.iGroupIdx]->RunMaster(); + } + else + { + PLImp("I'm follower, not run master damon."); + } + } + } +} + +int PNode :: Init(const Options & oOptions, NetWork *& poNetWork) +{ + int ret = CheckOptions(oOptions); + if (ret != 0) + { + PLErr("CheckOptions fail, ret %d", ret); + return ret; + } + + m_iMyNodeID = oOptions.oMyNode.GetNodeID(); + + //step1 init logstorage + LogStorage * poLogStorage = nullptr; + ret = InitLogStorage(oOptions, poLogStorage); + if (ret != 0) + { + return ret; + } + + //step2 init network + ret = InitNetWork(oOptions, poNetWork); + if (ret != 0) + { + return ret; + } + + //step3 build masterlist + for (int iGroupIdx = 0; iGroupIdx < oOptions.iGroupCount; iGroupIdx++) + { + MasterDamon * poMaster = new MasterDamon(this, iGroupIdx, poLogStorage); + + assert(poMaster != nullptr); + + ret = poMaster->Init(); + if (ret != 0) + { + return ret; + } + + m_vecMasterList.push_back(poMaster); + } + + //step4 build grouplist + for (int iGroupIdx = 0; iGroupIdx < oOptions.iGroupCount; iGroupIdx++) + { + Group * poGroup = new Group(poLogStorage, poNetWork, m_vecMasterList[iGroupIdx]->GetMasterSM(), iGroupIdx, oOptions); + + assert(poGroup != nullptr); + + m_vecGroupList.push_back(poGroup); + } + + //step5 init statemachine + InitStateMachine(oOptions); + + //step6 init group + for (auto & poGroup : m_vecGroupList) + { + int ret = poGroup->Init(); + if (ret != 0) + { + return ret; + } + } + + PLHead("OK"); + + return 0; +} + +bool PNode :: CheckGroupID(const int iGroupIdx) +{ + if (iGroupIdx < 0 || iGroupIdx >= (int)m_vecGroupList.size()) + { + return false; + } + + return true; +} + +int PNode :: Propose(const int iGroupIdx, const std::string & sValue, uint64_t & llInstanceID) +{ + if (!CheckGroupID(iGroupIdx)) + { + return Paxos_GroupIdxWrong; + } + + return m_vecGroupList[iGroupIdx]->GetCommitter()->NewValueGetID(sValue, llInstanceID); +} + +int PNode :: Propose(const int iGroupIdx, const std::string & sValue, uint64_t & llInstanceID, StateMachine * poSM) +{ + if (!CheckGroupID(iGroupIdx)) + { + return Paxos_GroupIdxWrong; + } + + return m_vecGroupList[iGroupIdx]->GetCommitter()->NewValueGetID(sValue, llInstanceID, poSM, nullptr); +} + +int PNode :: Propose(const int iGroupIdx, const std::string & sValue, uint64_t & llInstanceID, SMCtx * poSMCtx) +{ + if (!CheckGroupID(iGroupIdx)) + { + return Paxos_GroupIdxWrong; + } + + return m_vecGroupList[iGroupIdx]->GetCommitter()->NewValueGetID(sValue, llInstanceID, nullptr, poSMCtx); +} + +const uint64_t PNode :: GetNowInstanceID(const int iGroupIdx) +{ + if (!CheckGroupID(iGroupIdx)) + { + return (uint64_t)-1; + } + + return m_vecGroupList[iGroupIdx]->GetInstance()->GetNowInstanceID(); +} + +int PNode :: OnReceiveMessage(const char * pcMessage, const int iMessageLen) +{ + if (pcMessage == nullptr || iMessageLen <= 0) + { + PLErr("Message size %d to small, not valid.", iMessageLen); + return -2; + } + + int iGroupIdx = -1; + + memcpy(&iGroupIdx, pcMessage, GROUPIDXLEN); + + if (!CheckGroupID(iGroupIdx)) + { + PLErr("Message groupid %d wrong, groupsize %zu", iGroupIdx, m_vecGroupList.size()); + return Paxos_GroupIdxWrong; + } + + return m_vecGroupList[iGroupIdx]->GetInstance()->OnReceiveMessage(pcMessage, iMessageLen); +} + +void PNode :: AddStateMachine(StateMachine * poSM) +{ + for (auto & poGroup : m_vecGroupList) + { + poGroup->AddStateMachine(poSM); + } +} + +void PNode :: AddStateMachine(const int iGroupIdx, StateMachine * poSM) +{ + if (!CheckGroupID(iGroupIdx)) + { + return; + } + + m_vecGroupList[iGroupIdx]->AddStateMachine(poSM); +} + +const nodeid_t PNode :: GetMyNodeID() const +{ + return m_iMyNodeID; +} + +void PNode :: SetTimeoutMs(const int iTimeoutMs) +{ + for (auto & poGroup : m_vecGroupList) + { + poGroup->GetCommitter()->SetTimeoutMs(iTimeoutMs); + } +} + +//////////////////////////////////////////////////////////////////////// + +void PNode :: SetHoldPaxosLogCount(const uint64_t llHoldCount) +{ + for (auto & poGroup : m_vecGroupList) + { + poGroup->GetCheckpointCleaner()->SetHoldPaxosLogCount(llHoldCount); + } +} + +void PNode :: PauseCheckpointReplayer() +{ + for (auto & poGroup : m_vecGroupList) + { + poGroup->GetCheckpointReplayer()->Pause(); + } +} + +void PNode :: ContinueCheckpointReplayer() +{ + for (auto & poGroup : m_vecGroupList) + { + poGroup->GetCheckpointReplayer()->Continue(); + } +} + +void PNode :: PausePaxosLogCleaner() +{ + for (auto & poGroup : m_vecGroupList) + { + poGroup->GetCheckpointCleaner()->Pause(); + } +} + +void PNode :: ContinuePaxosLogCleaner() +{ + for (auto & poGroup : m_vecGroupList) + { + poGroup->GetCheckpointCleaner()->Continue(); + } +} + +/////////////////////////////////////////////////////// + +const NodeInfo PNode :: GetMaster(const int iGroupIdx) +{ + if (!CheckGroupID(iGroupIdx)) + { + return NodeInfo(nullnode); + } + + return NodeInfo(m_vecMasterList[iGroupIdx]->GetMasterSM()->GetMaster()); +} + +const bool PNode :: IsIMMaster(const int iGroupIdx) +{ + if (!CheckGroupID(iGroupIdx)) + { + return false; + } + + return m_vecMasterList[iGroupIdx]->GetMasterSM()->IsIMMaster(); +} + +int PNode :: SetMasterLease(const int iGroupIdx, const int iLeaseTimeMs) +{ + if (!CheckGroupID(iGroupIdx)) + { + return Paxos_GroupIdxWrong; + } + + m_vecMasterList[iGroupIdx]->SetLeaseTime(iLeaseTimeMs); + return 0; +} + +int PNode :: DropMaster(const int iGroupIdx) +{ + if (!CheckGroupID(iGroupIdx)) + { + return Paxos_GroupIdxWrong; + } + + m_vecMasterList[iGroupIdx]->DropMaster(); + return 0; +} + +} + diff --git a/src/node/pnode.h b/src/node/pnode.h new file mode 100644 index 000000000..3be87d775 --- /dev/null +++ b/src/node/pnode.h @@ -0,0 +1,112 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/node.h" +#include "phxpaxos/options.h" +#include +#include "db.h" +#include "dfnetwork.h" +#include "group.h" +#include "master_damon.h" + +namespace phxpaxos +{ + +class PNode : public Node +{ +public: + PNode(); + + ~PNode(); + + int Init(const Options & oOptions, NetWork *& poNetWork); + +public: + int Propose(const int iGroupIdx, const std::string & sValue, uint64_t & llInstanceID); + + int Propose(const int iGroupIdx, const std::string & sValue, uint64_t & llInstanceID, StateMachine * poSM); + + int Propose(const int iGroupIdx, const std::string & sValue, uint64_t & llInstanceID, SMCtx * poSMCtx); + + const uint64_t GetNowInstanceID(const int iGroupIdx); + +public: + void AddStateMachine(StateMachine * poSM); + + void AddStateMachine(const int iGroupIdx, StateMachine * poSM); + + int OnReceiveMessage(const char * pcMessage, const int iMessageLen); + + const nodeid_t GetMyNodeID() const; + + void SetTimeoutMs(const int iTimeoutMs); + +public: + void SetHoldPaxosLogCount(const uint64_t llHoldCount); + + void PauseCheckpointReplayer(); + + void ContinueCheckpointReplayer(); + + void PausePaxosLogCleaner(); + + void ContinuePaxosLogCleaner(); + +public: + //master + + const NodeInfo GetMaster(const int iGroupIdx); + + const bool IsIMMaster(const int iGroupIdx); + + int SetMasterLease(const int iGroupIdx, const int iLeaseTimeMs); + + int DropMaster(const int iGroupIdx); + +private: + int CheckOptions(const Options & oOptions); + + int InitLogStorage(const Options & oOptions, LogStorage *& poLogStorage); + + int InitNetWork(const Options & oOptions, NetWork *& poNetWork); + + int InitMaster(const Options & oOptions); + + void InitStateMachine(const Options & oOptions); + + bool CheckGroupID(const int iGroupIdx); + +private: + std::vector m_vecGroupList; + +private: + std::vector m_vecMasterList; + +private: + MultiDatabase m_oDefaultLogStorage; + DFNetWork m_oDefaultNetWork; + + nodeid_t m_iMyNodeID; +}; + +} diff --git a/src/sm-base/Makefile.define b/src/sm-base/Makefile.define new file mode 100644 index 000000000..93f311eec --- /dev/null +++ b/src/sm-base/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libsmbase.a + +SMBASE_OBJ=sm_base.o sm.o + +SMBASE_LIB=smbase src/comm:comm include:include + +SMBASE_SYS_LIB= + +SMBASE_INCS=$(SRC_BASE_PATH)/src/sm-base + +SMBASE_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/sm-base/sm.cpp b/src/sm-base/sm.cpp new file mode 100644 index 000000000..90adecc61 --- /dev/null +++ b/src/sm-base/sm.cpp @@ -0,0 +1,69 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "phxpaxos/sm.h" + +namespace phxpaxos +{ + +SMCtx :: SMCtx(const int iSMID, void * pCtx) : m_iSMID(iSMID), m_pCtx(pCtx) +{ +} + +SMCtx :: SMCtx() : m_iSMID(0), m_pCtx(nullptr) +{ +} + +bool StateMachine :: ExecuteForCheckpoint(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue) +{ + return true; +} + +const uint64_t StateMachine :: GetCheckpointInstanceID(const int iGroupIdx) const +{ + return phxpaxos::NoCheckpoint; +} + +//default no checkpoint +int StateMachine :: GetCheckpointState(const int iGroupIdx, std::string & sDirPath, + std::vector & vecFileList) +{ + return -1; +} + +int StateMachine :: LoadCheckpointState(const int iGroupIdx, const std::string & sCheckpointTmpFileDirPath, + const std::vector & vecFileList, const uint64_t llCheckpointInstanceID) +{ + return -1; +} + +int StateMachine :: LockCheckpointState() +{ + return -1; +} + +void StateMachine :: UnLockCheckpointState() +{ +} + +} + diff --git a/src/sm-base/sm_base.cpp b/src/sm-base/sm_base.cpp new file mode 100644 index 000000000..231ebf586 --- /dev/null +++ b/src/sm-base/sm_base.cpp @@ -0,0 +1,200 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "commdef.h" +#include "sm_base.h" +#include + +using namespace std; + +namespace phxpaxos +{ + +SMFac :: SMFac() +{ +} + +SMFac :: ~SMFac() +{ +} + +bool SMFac :: DoExecute(StateMachine * poSM, const int iGroupIdx, + const uint64_t llInstanceID, const std::string & sPaxosValue, SMCtx * poSMCtx) +{ + std::string sBodyValue = string(sPaxosValue.data() + sizeof(int), sPaxosValue.size() - sizeof(int)); + return poSM->Execute(iGroupIdx, llInstanceID, sBodyValue, poSMCtx); +} + +bool SMFac :: Execute(const int iGroupIdx, const uint64_t llInstanceID, const std::string & sPaxosValue, SMCtx * poSMCtx) +{ + if (sPaxosValue.size() < sizeof(int)) + { + PLErr("Value wrong, instanceid %lu size %zu", llInstanceID, sPaxosValue.size()); + //need do nothing, just skip + return true; + } + + int iSMID = 0; + memcpy(&iSMID, sPaxosValue.data(), sizeof(int)); + + if (iSMID == 0) + { + PLImp("Value no need to do sm, just skip, instanceid %lu", llInstanceID); + return true; + } + + if (m_vecSMList.size() == 0) + { + PLImp("No any sm, need wait sm, instanceid %lu", llInstanceID); + return false; + } + + for (auto & poSM : m_vecSMList) + { + if (poSM->SMID() == iSMID) + { + return DoExecute(poSM, iGroupIdx, llInstanceID, sPaxosValue, poSMCtx); + } + } + + PLErr("Unknown smid %d instanceid %lu", iSMID, llInstanceID); + + return false; +} + +bool SMFac :: ExecuteForCheckpoint(const int iGroupIdx, const uint64_t llInstanceID, const std::string & sPaxosValue) +{ + if (sPaxosValue.size() < sizeof(int)) + { + PLErr("Value wrong, instanceid %lu size %zu", llInstanceID, sPaxosValue.size()); + //need do nothing, just skip + return true; + } + + int iSMID = 0; + memcpy(&iSMID, sPaxosValue.data(), sizeof(int)); + + if (iSMID == 0) + { + PLImp("Value no need to do sm, just skip, instanceid %lu", llInstanceID); + return true; + } + + if (m_vecSMList.size() == 0) + { + PLImp("No any sm, need wait sm, instanceid %lu", llInstanceID); + return false; + } + + for (auto & poSM : m_vecSMList) + { + if (poSM->SMID() == iSMID) + { + std::string sBodyValue = string(sPaxosValue.data() + sizeof(int), sPaxosValue.size() - sizeof(int)); + return poSM->ExecuteForCheckpoint(iGroupIdx, llInstanceID, sBodyValue); + } + } + + PLErr("Unknown smid %d instanceid %lu", iSMID, llInstanceID); + + return false; +} + + +void SMFac :: PackPaxosValue(std::string & sPaxosValue, const int iSMID) +{ + char sSMID[sizeof(int)] = {0}; + if (iSMID != 0) + { + memcpy(sSMID, &iSMID, sizeof(sSMID)); + } + + sPaxosValue = string(sSMID, sizeof(sSMID)) + sPaxosValue; +} + +void SMFac :: AddSM(StateMachine * poSM) +{ + for (auto & poSMt : m_vecSMList) + { + if (poSMt->SMID() == poSM->SMID()) + { + return; + } + } + + m_vecSMList.push_back(poSM); +} + +/////////////////////////////////////////////////////// + +const uint64_t SMFac :: GetCheckpointInstanceID(const int iGroupIdx) const +{ + uint64_t llCPInstanceID = -1; + uint64_t llCPInstanceID_Insize = -1; + bool bHaveUseSM = false; + + for (auto & poSM : m_vecSMList) + { + if (poSM->SMID() == SYSTEM_V_SMID + || poSM->SMID() == MASTER_V_SMID) + { + //system variables + //master variables + //if no user state machine, system and master's can use. + //if have user state machine, use user'state machine's checkpointinstanceid. + if (poSM->GetCheckpointInstanceID(iGroupIdx) == uint64_t(-1)) + { + continue; + } + + if (poSM->GetCheckpointInstanceID(iGroupIdx) > llCPInstanceID_Insize + || llCPInstanceID_Insize == (uint64_t)-1) + { + llCPInstanceID_Insize = poSM->GetCheckpointInstanceID(iGroupIdx); + } + + continue; + } + + bHaveUseSM = true; + + if (poSM->GetCheckpointInstanceID(iGroupIdx) == uint64_t(-1)) + { + continue; + } + + if (poSM->GetCheckpointInstanceID(iGroupIdx) > llCPInstanceID + || llCPInstanceID == (uint64_t)-1) + { + llCPInstanceID = poSM->GetCheckpointInstanceID(iGroupIdx); + } + } + + return bHaveUseSM ? llCPInstanceID : llCPInstanceID_Insize; +} + +std::vector SMFac :: GetSMList() +{ + return m_vecSMList; +} + +} + diff --git a/src/sm-base/sm_base.h b/src/sm-base/sm_base.h new file mode 100644 index 000000000..171db502d --- /dev/null +++ b/src/sm-base/sm_base.h @@ -0,0 +1,61 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "commdef.h" +#include +#include "phxpaxos/sm.h" + +namespace phxpaxos +{ + +class SMFac +{ +public: + SMFac(); + ~SMFac(); + + bool DoExecute(StateMachine * poSM, const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, SMCtx * poSMCtx); + + bool Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, SMCtx * poSMCtx); + + bool ExecuteForCheckpoint(const int iGroupIdx, const uint64_t llInstanceID, const std::string & sPaxosValue); + + void PackPaxosValue(std::string & sPaxosValue, const int iSMID = 0); + + void AddSM(StateMachine * poSM); + +public: + const uint64_t GetCheckpointInstanceID(const int iGroupIdx) const; + + std::vector GetSMList(); + +public: + + +private: + std::vector m_vecSMList; +}; + +} diff --git a/src/test/Makefile.define b/src/test/Makefile.define new file mode 100644 index 000000000..8f224b85a --- /dev/null +++ b/src/test/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=phx_paxos_test + +PHX_PAXOS_TEST_OBJ=test_sm.o test_server.o test_main.o + +PHX_PAXOS_TEST_LIB=src/utils:utils + +PHX_PAXOS_TEST_SYS_LIB=$(PHXPAXOS_LIB_PATH)/libphxpaxos.a $(LEVELDB_LIB_PATH)/libleveldb.a $(PROTOBUF_LIB_PATH)/libprotobuf.a -lpthread + +PHX_PAXOS_TEST_INCS=$(SRC_BASE_PATH)/src/test $(PHXPAXOS_INCLUDE_PATH) $(LEVELDB_INCLUDE_PATH) $(PROTOBUF_INCLUDE_PATH) + +PHX_PAXOS_TEST_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/test/test_main.cpp b/src/test/test_main.cpp new file mode 100644 index 000000000..29c9fd961 --- /dev/null +++ b/src/test/test_main.cpp @@ -0,0 +1,369 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "test_server.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "phxpaxos/options.h" +#include "utils_include.h" +#include +#include + +using namespace phxpaxos_test; +using namespace phxpaxos; +using namespace std; + +int giRunNodeCount = 3; + +void RandValue(const int iSize, string & sValue) +{ + sValue = ""; + int iRealSize = rand() % iSize + iSize / 2; + + for (int i = 0; i < iRealSize; i++) + { + sValue += ('a' + (rand() % 26)); + } +} + +class TestSuccWrite +{ +public: + TestSuccWrite() { } + + int AddSuccWrite(const uint64_t llInstanceID, const string & sWriteValue) + { + m_oMutex.lock(); + + if (m_mapSuccWrite.find(llInstanceID) != end(m_mapSuccWrite)) + { + m_oMutex.unlock(); + return -1; + } + + m_mapSuccWrite[llInstanceID] = sWriteValue; + m_oMutex.unlock(); + + return 0; + } + + vector > ToVector() + { + m_oMutex.lock(); + + if (m_vecSuccWrite.size() != m_mapSuccWrite.size()) + { + m_vecSuccWrite.clear(); + for (auto & it : m_mapSuccWrite) + { + m_vecSuccWrite.push_back(make_pair(it.first, it.second)); + } + } + + m_oMutex.unlock(); + return m_vecSuccWrite; + } + +public: + Mutex m_oMutex; + map m_mapSuccWrite; + vector > m_vecSuccWrite; +}; + +TestSuccWrite goSuccWrite; + +class TestClient : public phxpaxos::Thread +{ +public: + TestClient(TestServer * poTestServer, const int iWriteCount, const int iAvgValueSize) : + m_poTestServer(poTestServer), m_iWriteCount(iWriteCount), m_iAvgValueSize(iAvgValueSize), m_iRunRet(0) { } + + ~TestClient() { } + + void run() + { + string sValue; + for (int i = 0; i < m_iWriteCount; i++) + { + RandValue(m_iAvgValueSize, sValue); + + while (true) + { + uint64_t llInstanceID = 0; + int ret = m_poTestServer->Write(sValue, llInstanceID); + if (ret != PaxosTryCommitRet_OK && ret != PaxosTryCommitRet_Conflict) + { + printf("write fail, ret %d\n", ret); + m_iRunRet = -1; + return; + } + else if (ret == PaxosTryCommitRet_Conflict) + { + continue; + } + else + { + ret = goSuccWrite.AddSuccWrite(llInstanceID, sValue); + if (ret != 0) + { + printf("this instance already exist, is error, instanceid %lu value %s\n", llInstanceID, sValue.c_str()); + m_iRunRet = -1; + return; + } + break; + } + } + } + } + + const int RunRet() { return m_iRunRet; } + +private: + TestServer * m_poTestServer; + int m_iWriteCount; + int m_iAvgValueSize; + + int m_iRunRet; +}; + +///////////////////////////////////////////////////////////////////////////// +bool CheckCorrect(vector & vecTestServerList) +{ + for (auto & poTestServer : vecTestServerList) + { + if (!poTestServer->GetSM()->CheckExecuteValueCorrect(goSuccWrite.ToVector())) + { + return false; + } + } + + return true; +} + +int RunServer(vector & vecTestServerList) +{ + string sIP = "127.0.0.1"; + int iPort = 11112; + int iServerCount = giRunNodeCount; + NodeInfoList vecNodeList; + + for (int i = 0; i < iServerCount; i++) + { + NodeInfo oNode(sIP, iPort + i); + vecNodeList.push_back(oNode); + } + + for (int i = 0; i < iServerCount; i++) + { + NodeInfo oMyNode(sIP, iPort + i); + TestServer * poTestServer = new TestServer(oMyNode, vecNodeList); + assert(poTestServer != nullptr); + vecTestServerList.push_back(poTestServer); + + int ret = poTestServer->RunPaxos(); + if (ret != 0) + { + return ret; + } + } + + return 0; +} + +int ReadyServer(vector & vecTestServerList) +{ + //wait all thread is started. + Time::MsSleep(50); + + for (auto & poTestServer : vecTestServerList) + { + int ret = poTestServer->Ready(); + if (ret != 0) + { + return ret; + } + } + + return 0; +} + +void EndServer(vector & vecTestServerList) +{ + for (auto & poTestServer : vecTestServerList) + { + delete poTestServer; + } +} + +void ShutDownOneNode(vector & vecTestServerList) +{ + printf("\nstart shutdown one node........\n"); + if (vecTestServerList.size() > 0) + { + delete vecTestServerList[0]; + vecTestServerList.erase(vecTestServerList.begin()); + } +} + +///////////////////////////////////////////////////////////// + +bool Test_OnlyOneNode_Write(vector & vecTestServerList) +{ + TimeStat oTimeStat; + oTimeStat.Point(); + + TestServer * poTestServer = vecTestServerList[0]; + + TestClient oClient(poTestServer, 100, 20); + oClient.start(); + oClient.join(); + + printf("write done, usetime %dms, runret %s, nowsuccwritecount %zu\n", + oTimeStat.Point(), oClient.RunRet() == 0 ? "succ" : "fail", goSuccWrite.m_mapSuccWrite.size()); + if (oClient.RunRet() != 0) + { + return false; + } + + printf("wait 5 second let all node learn to latest...\n"); + Time::MsSleep(5000); + + if (!CheckCorrect(vecTestServerList)) + { + return false; + } + + return true; +} + +bool Test_AllNode_Write_Parallel(vector & vecTestServerList) +{ + TimeStat oTimeStat; + oTimeStat.Point(); + + vector vecClient; + for (auto & poTestServer : vecTestServerList) + { + TestClient * poClient = new TestClient(poTestServer, 100, 20); + poClient->start(); + vecClient.push_back(poClient); + } + + bool bRunRet = true; + for (auto & poClient : vecClient) + { + poClient->join(); + if (poClient->RunRet() != 0) + { + bRunRet = false; + } + delete poClient; + } + + printf("write done, usetime %dms, runret %s, succwritecount %zu\n", + oTimeStat.Point(), bRunRet ? "succ" : "fail", goSuccWrite.m_mapSuccWrite.size()); + if (!bRunRet) + { + return false; + } + + printf("wait 5 second let all node learn to latest...\n"); + Time::MsSleep(5000); + + if (!CheckCorrect(vecTestServerList)) + { + return false; + } + + return true; +} + +void Test(vector & vecTestServerList) +{ + printf("\nstart test round, runnode %zu\n", vecTestServerList.size()); + printf("start Test_OnlyOneNode_Write................\n"); + if (Test_OnlyOneNode_Write(vecTestServerList)) + { + printf("Test_OnlyOneNode_Write pass...\n"); + } + else + { + printf("Test_OnlyOneNode_Write fail...\n"); + } + + printf("\nstart Test_AllNode_Write_Parallel................\n"); + if (Test_AllNode_Write_Parallel(vecTestServerList)) + { + printf("Test_AllNode_Write_Parallel pass...\n"); + } + else + { + printf("Test_AllNode_Write_Parallel fail...\n"); + } +} + +int main(int argc, char ** argv) +{ + if (argc < 2) + { + printf("%s \n", argv[0]); + return -1; + } + + giRunNodeCount = atoi(argv[1]); + + vector vecTestServerList; + + int ret = RunServer(vecTestServerList); + if (ret != 0) + { + EndServer(vecTestServerList); + return -1; + } + + ret = ReadyServer(vecTestServerList); + if (ret != 0) + { + EndServer(vecTestServerList); + return -1; + } + + Test(vecTestServerList); + + while ((int)vecTestServerList.size() > (giRunNodeCount / 2 + 1)) + { + ShutDownOneNode(vecTestServerList); + Test(vecTestServerList); + } + + EndServer(vecTestServerList); + + return 0; +} + diff --git a/src/test/test_server.cpp b/src/test/test_server.cpp new file mode 100644 index 000000000..7da102e09 --- /dev/null +++ b/src/test/test_server.cpp @@ -0,0 +1,138 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "test_server.h" +#include +#include +#include +#include +#include +#include +#include "utils_include.h" + +using namespace phxpaxos; +using namespace std; + +namespace phxpaxos_test +{ + +TestServer :: TestServer(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList) + : m_oMyNode(oMyNode), m_vecNodeList(vecNodeList), m_poPaxosNode(nullptr) +{ +} + +TestServer :: ~TestServer() +{ + printf("start end server ip %s port %d\n", m_oMyNode.GetIP().c_str(), m_oMyNode.GetPort()); + delete m_poPaxosNode; + printf("server ip %s port %d ended\n", m_oMyNode.GetIP().c_str(), m_oMyNode.GetPort()); +} + +int TestServer :: MakeLogStoragePath(std::string & sLogStoragePath) +{ + char sTmp[128] = {0}; + snprintf(sTmp, sizeof(sTmp), "./logpath_%s_%d", m_oMyNode.GetIP().c_str(), m_oMyNode.GetPort()); + + sLogStoragePath = string(sTmp); + + if (access(sLogStoragePath.c_str(), F_OK) != -1) + { + if (FileUtils :: DeleteDir(sLogStoragePath) != 0) + { + printf("Delete exist logstorage dir fail\n"); + return -1; + } + } + + if (mkdir(sLogStoragePath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) + { + printf("Create dir fail, path %s\n", sLogStoragePath.c_str()); + return -1; + } + + return 0; +} + +int TestServer :: RunPaxos() +{ + Options oOptions; + + int ret = MakeLogStoragePath(oOptions.sLogStoragePath); + if (ret != 0) + { + return ret; + } + + oOptions.iGroupCount = 1; + + oOptions.oMyNode = m_oMyNode; + oOptions.vecNodeInfoList = m_vecNodeList; + + GroupSMInfo oSMInfo; + oSMInfo.iGroupIdx = 0; + oSMInfo.vecSMList.push_back(&m_oTestSM); + oOptions.vecGroupSMInfoList.push_back(oSMInfo); + + ret = Node::RunNode(oOptions, m_poPaxosNode); + if (ret != 0) + { + printf("run paxos fail, ret %d\n", ret); + return ret; + } + + printf("run paxos ok, ip %s port %d\n", m_oMyNode.GetIP().c_str(), m_oMyNode.GetPort()); + return 0; +} + +int TestServer :: Write(const std::string & sTestValue, uint64_t & llInstanceID) +{ + SMCtx oCtx; + oCtx.m_iSMID = 1; + oCtx.m_pCtx = nullptr; + + int ret = m_poPaxosNode->Propose(0, sTestValue, llInstanceID, &oCtx); + if (ret != 0) + { + return ret; + } + + return 0; +} + +int TestServer :: Ready() +{ + uint64_t llInstanceID = 0; + int ret = m_poPaxosNode->Propose(0, "nullvalue", llInstanceID); + if (ret == 0) + { + printf("ready paxos ok, ip %s port %d\n", m_oMyNode.GetIP().c_str(), m_oMyNode.GetPort()); + } + + return ret; +} + +TestSM * TestServer :: GetSM() +{ + return &m_oTestSM; +} + +} + diff --git a/src/test/test_server.h b/src/test/test_server.h new file mode 100644 index 000000000..405204a31 --- /dev/null +++ b/src/test/test_server.h @@ -0,0 +1,60 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/node.h" +#include "test_sm.h" +#include +#include + +namespace phxpaxos_test +{ + +class TestServer +{ +public: + TestServer(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList); + ~TestServer(); + + int RunPaxos(); + + int Write(const std::string & sTestValue, uint64_t & llInstanceID); + + int Ready(); + + TestSM * GetSM(); + +private: + int MakeLogStoragePath(std::string & sLogStoragePath); + +private: + phxpaxos::NodeInfo m_oMyNode; + phxpaxos::NodeInfoList m_vecNodeList; + + TestSM m_oTestSM; + + phxpaxos::Node * m_poPaxosNode; +}; + +} + + diff --git a/src/test/test_sm.cpp b/src/test/test_sm.cpp new file mode 100644 index 000000000..d4cdfc54c --- /dev/null +++ b/src/test/test_sm.cpp @@ -0,0 +1,82 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "test_sm.h" + +using namespace phxpaxos; +using namespace std; + +namespace phxpaxos_test +{ + +TestSM :: TestSM() +{ +} + +bool TestSM :: Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, SMCtx * poSMCtx) +{ + m_vecExecuted.push_back(make_pair(llInstanceID, sPaxosValue)); + return true; +} + +bool TestSM :: CheckExecuteValueCorrect(const std::vector > & vecOtherExecuted) +{ + if (vecOtherExecuted.size() != m_vecExecuted.size()) + { + return false; + } + + if (vecOtherExecuted.size() == 0) + { + return true; + } + + uint64_t llNowInstanceID = m_vecExecuted[0].first; + for (auto & it : m_vecExecuted) + { + if (it.first != llNowInstanceID) + { + printf("instanceid not serial, expect %lu actual %lu\n", + llNowInstanceID, it.first); + return false; + } + + llNowInstanceID++; + } + + for (size_t i = 0; i < m_vecExecuted.size(); i++) + { + if (m_vecExecuted[i].first != vecOtherExecuted[i].first + || m_vecExecuted[i].second != vecOtherExecuted[i].second) + { + printf("not same %lu %s | %lu %s\n", + m_vecExecuted[i].first, m_vecExecuted[i].second.c_str(), + vecOtherExecuted[i].first, vecOtherExecuted[i].second.c_str()); + return false; + } + } + + return true; +} + +} + diff --git a/src/test/test_sm.h b/src/test/test_sm.h new file mode 100644 index 000000000..43de99758 --- /dev/null +++ b/src/test/test_sm.h @@ -0,0 +1,50 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "phxpaxos/sm.h" +#include "phxpaxos/options.h" +#include +#include +#include +#include + +namespace phxpaxos_test +{ + +class TestSM : public phxpaxos::StateMachine +{ +public: + TestSM(); + + bool Execute(const int iGroupIdx, const uint64_t llInstanceID, + const std::string & sPaxosValue, phxpaxos::SMCtx * poSMCtx); + + const int SMID() const { return 1; } + + bool CheckExecuteValueCorrect(const std::vector > & vecOtherExecuted); + +public: + std::vector > m_vecExecuted; +}; + +} diff --git a/src/tools/Makefile.define b/src/tools/Makefile.define new file mode 100644 index 000000000..bc57f606d --- /dev/null +++ b/src/tools/Makefile.define @@ -0,0 +1,41 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=system_variables_tools paxos_log_tools + +SYSTEM_VARIABLES_TOOLS_OBJ=system_variables_tools.o + +SYSTEM_VARIABLES_TOOLS_LIB=src/comm:comm src/config:config src/logstorage:logstorage + +SYSTEM_VARIABLES_TOOLS_SYS_LIB= + +SYSTEM_VARIABLES_TOOLS_INCS=$(SRC_BASE_PATH)/src/tools + +SYSTEM_VARIABLES_TOOLS_EXTRA_CPPFLAGS=-Wall -Werror + +PAXOS_LOG_TOOLS_OBJ=paxos_log_tools.o + +PAXOS_LOG_TOOLS_LIB=src/comm:comm src/logstorage:logstorage + +PAXOS_LOG_TOOLS_SYS_LIB= + +PAXOS_LOG_TOOLS_INCS=$(SRC_BASE_PATH)/src/tools + +PAXOS_LOG_TOOLS_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/tools/paxos_log_tools.cpp b/src/tools/paxos_log_tools.cpp new file mode 100644 index 000000000..858a75b1c --- /dev/null +++ b/src/tools/paxos_log_tools.cpp @@ -0,0 +1,96 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "db.h" +#include +#include + +using namespace std; +using namespace phxpaxos; + +void DelInstance(const int iGroupIdx, MultiDatabase & oLogStorage, uint64_t llInstanceID) +{ + string sValue; + int ret = oLogStorage.Get(iGroupIdx, llInstanceID, sValue); + if (ret != 0) + { + printf("get this instance %lu fail, do you want to delete it? (y/n)\n", llInstanceID); + } + else + { + printf("this instance %lu value size is %zu, do you want to delete it? (y/n)\n", + llInstanceID, sValue.size()); + } + + string c = "n"; + cin >> c; + + if (c == "y") + { + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + ret = oLogStorage.ForceDel(oWriteOptions, iGroupIdx, llInstanceID); + if (ret != 0) + { + printf("delete instance %lu fail\n", llInstanceID); + } + else + { + printf("delete instance %lu ok\n", llInstanceID); + } + } +} + +int main(int argc, char ** argv) +{ + if (argc < 5) + { + printf("%s \n", argv[0]); + return -1; + } + + string sPaxosLogPath = argv[1]; + int iGroupIdx = atoi(argv[2]); + + if (sPaxosLogPath.size() == 0) + { + printf("paxos log path not valid, path %s\n", sPaxosLogPath.c_str()); + return -1; + } + + MultiDatabase oDefaultLogStorage; + int ret = oDefaultLogStorage.Init(sPaxosLogPath, iGroupIdx + 1); + if (ret != 0) + { + printf("init log storage fail, ret %d\n", ret); + return ret; + } + + string sOP = string(argv[3]); + uint64_t llInstanceID = strtoull(argv[4], NULL, 10); + if (sOP == "del") + { + DelInstance(iGroupIdx, oDefaultLogStorage, llInstanceID); + } + + return 0; +} + diff --git a/src/tools/run_svm_tools.sh b/src/tools/run_svm_tools.sh new file mode 100644 index 000000000..d1b586ba5 --- /dev/null +++ b/src/tools/run_svm_tools.sh @@ -0,0 +1 @@ +/home/lynncui/phoenix/build64_debug/phxcomm/paxos/paxoslib/tools/system_variables_tools /home/lynncui/phoenix/phxcomm/paxos/paxoslib/test/db/node3 0 $1 $2 diff --git a/src/tools/system_variables_tools.cpp b/src/tools/system_variables_tools.cpp new file mode 100644 index 000000000..c7c255e17 --- /dev/null +++ b/src/tools/system_variables_tools.cpp @@ -0,0 +1,118 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "db.h" +#include +#include +#include "config_include.h" + +using namespace std; +using namespace phxpaxos; + +void ShowVariables(SystemVSM & oVSM) +{ + SystemVariables oVariables; + oVSM.GetSystemVariables(oVariables); + + printf("gid %llu\n", oVariables.gid()); + printf("version %llu\n", oVariables.version()); + + for (int i = 0; i < oVariables.membership_size(); i++) + { + PaxosNodeInfo oNodeInfo = oVariables.membership(i); + NodeInfo tTmpNode(oNodeInfo.nodeid()); + + printf("ip %s port %d nodeid %lu\n", + tTmpNode.GetIP().c_str(), tTmpNode.GetPort(), tTmpNode.GetNodeID()); + } +} + +void ModGid(SystemVSM & oVSM, const uint64_t llGid) +{ + SystemVariables oVariables; + oVSM.GetSystemVariables(oVariables); + + oVariables.set_gid(llGid); + + int ret = oVSM.UpdateSystemVariables(oVariables); + if (ret != 0) + { + printf("mod gid fail, ret %d gid %lu\n", ret, llGid); + } + else + { + printf("after mod gid:\n"); + ShowVariables(oVSM); + } +} + +int main(int argc, char ** argv) +{ + if (argc < 4) + { + printf("%s \n", argv[0]); + return -1; + } + + string sPaxosLogPath = argv[1]; + int iGroupIdx = atoi(argv[2]); + + if (sPaxosLogPath.size() == 0) + { + printf("paxos log path not valid, path %s\n", sPaxosLogPath.c_str()); + return -1; + } + + MultiDatabase oDefaultLogStorage; + int ret = oDefaultLogStorage.Init(sPaxosLogPath, iGroupIdx + 1); + if (ret != 0) + { + printf("init log storage fail, ret %d\n", ret); + return ret; + } + + SystemVSM oVSM(iGroupIdx, nullnode, &oDefaultLogStorage); + ret = oVSM.Init(); + if (ret != 0) + { + printf("system variable sm init fail, ret %d\n", ret); + return ret; + } + + string sOP = string(argv[3]); + if (sOP == "show") + { + ShowVariables(oVSM); + } + else if (sOP == "modgid") + { + if (argc < 5) + { + printf("no gid to mod\n"); + } + + uint64_t llGid = strtoull(argv[4], NULL, 10); + ModGid(oVSM, llGid); + } + + return 0; +} + diff --git a/src/ut/Makefile.define b/src/ut/Makefile.define new file mode 100644 index 000000000..e982c4992 --- /dev/null +++ b/src/ut/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=phxpaxos_ut + +PHXPAXOS_UT_OBJ=ut_main.o db_ut.o nodeid_ut.o timer_ut.o wait_lock_ut.o make_class.o acceptor_ut.o proposer_ut.o + +PHXPAXOS_UT_LIB=src/logstorage:logstorage src/config:config src/algorithm:algorithm src/communicate:communicate + +PHXPAXOS_UT_SYS_LIB=$(SRC_BASE_PATH)/third_party/gmock/lib/libgmock.a $(SRC_BASE_PATH)/third_party/gmock/lib/libgmock_main.a $(SRC_BASE_PATH)/third_party/gtest/lib/libgtest.a + +PHXPAXOS_UT_INCS=$(SRC_BASE_PATH)/src/ut $(SRC_BASE_PATH)/third_party/gmock/include $(SRC_BASE_PATH)/third_party/gtest/include + +PHXPAXOS_UT_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/ut/acceptor_ut.cpp b/src/ut/acceptor_ut.cpp new file mode 100644 index 000000000..766c05994 --- /dev/null +++ b/src/ut/acceptor_ut.cpp @@ -0,0 +1,298 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include +#include "gmock/gmock.h" +#include "make_class.h" +#include "mock_class.h" + +using namespace phxpaxos; +using namespace std; +using ::testing::_; +using ::testing::Return; + + +class AcceptorBuilder +{ +public: + AcceptorBuilder() + { + MakeConfig(&oMockLogStorage, poConfig); + MakeCommunicate(&oMockNetWork, poConfig, poCommunicate); + MakeInstance(&oMockLogStorage, poConfig, poCommunicate, poInstance); + MakeAcceptor(&oMockLogStorage, poConfig, poCommunicate, poInstance, poAcceptor); + + poAcceptor->SetAsTestMode(); + + BP->SetInstance(&oMockBreakpoint); + } + + ~AcceptorBuilder() + { + delete poAcceptor; + delete poCommunicate; + delete poInstance; + delete poConfig; + BP->SetInstance(nullptr); + } + + MockNetWork oMockNetWork; + MockLogStorage oMockLogStorage; + Config * poConfig; + Communicate * poCommunicate; + Instance * poInstance; + Acceptor * poAcceptor; + + MockBreakpoint oMockBreakpoint; +}; + +TEST(Acceptor, OnPrepare_Promise) +{ + AcceptorBuilder ob; + + EXPECT_CALL(ob.oMockLogStorage, Put(_,_,_,_)).WillOnce(Return(0)); + + MockAcceptorBP & oAcceptorBP = ob.oMockBreakpoint.m_oMockAcceptorBP; + EXPECT_CALL(oAcceptorBP, OnPreparePass()).Times(1); + EXPECT_CALL(oAcceptorBP, OnPrepareReject()).Times(0); + + NodeInfo oMyNode = GetMyNode(); + + ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot = BallotNumber(1, oMyNode.GetNodeID()); + + PaxosMsg oPaxosMsg; + oPaxosMsg.set_instanceid(0); + oPaxosMsg.set_nodeid(oMyNode.GetNodeID()); + oPaxosMsg.set_proposalid(2); + oPaxosMsg.set_msgtype(phxpaxos::MsgType_PaxosPrepare); + + ob.poAcceptor->OnPrepare(oPaxosMsg); + + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot == BallotNumber(2, oMyNode.GetNodeID())); + + //second times + EXPECT_CALL(ob.oMockLogStorage, Put(_,_,_,_)).WillOnce(Return(0)); + + EXPECT_CALL(oAcceptorBP, OnPreparePass()).Times(1); + EXPECT_CALL(oAcceptorBP, OnPrepareReject()).Times(0); + + oPaxosMsg.set_instanceid(0); + oPaxosMsg.set_nodeid(oMyNode.GetNodeID()); + oPaxosMsg.set_proposalid(2); + oPaxosMsg.set_msgtype(phxpaxos::MsgType_PaxosPrepare); + + ob.poAcceptor->OnPrepare(oPaxosMsg); + + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot == BallotNumber(2, oMyNode.GetNodeID())); + + //third times + EXPECT_CALL(ob.oMockLogStorage, Put(_,_,_,_)).WillOnce(Return(0)); + + EXPECT_CALL(oAcceptorBP, OnPreparePass()).Times(1); + EXPECT_CALL(oAcceptorBP, OnPrepareReject()).Times(0); + + oPaxosMsg.set_instanceid(0); + oPaxosMsg.set_nodeid(oMyNode.GetNodeID()); + oPaxosMsg.set_proposalid(3); + oPaxosMsg.set_msgtype(phxpaxos::MsgType_PaxosPrepare); + + ob.poAcceptor->OnPrepare(oPaxosMsg); + + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot == BallotNumber(3, oMyNode.GetNodeID())); +} + +TEST(Acceptor, OnPrepare_Reject) +{ + AcceptorBuilder ob; + + EXPECT_CALL(ob.oMockLogStorage, Put(_,_,_,_)).Times(0); + + MockAcceptorBP & oAcceptorBP = ob.oMockBreakpoint.m_oMockAcceptorBP; + EXPECT_CALL(oAcceptorBP, OnPreparePass()).Times(0); + EXPECT_CALL(oAcceptorBP, OnPrepareReject()).Times(1); + + NodeInfo oMyNode = GetMyNode(); + + ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot = BallotNumber(2, oMyNode.GetNodeID()); + + PaxosMsg oPaxosMsg; + oPaxosMsg.set_instanceid(0); + oPaxosMsg.set_nodeid(oMyNode.GetNodeID()); + oPaxosMsg.set_proposalid(1); + oPaxosMsg.set_msgtype(phxpaxos::MsgType_PaxosPrepare); + + ob.poAcceptor->OnPrepare(oPaxosMsg); + + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot == BallotNumber(2, oMyNode.GetNodeID())); +} + +TEST(Acceptor, OnPrepare_PersistFail) +{ + AcceptorBuilder ob; + + EXPECT_CALL(ob.oMockLogStorage, Put(_,_,_,_)).WillOnce(Return(-1)); + + MockAcceptorBP & oAcceptorBP = ob.oMockBreakpoint.m_oMockAcceptorBP; + EXPECT_CALL(oAcceptorBP, OnPreparePass()).Times(0); + EXPECT_CALL(oAcceptorBP, OnPrepareReject()).Times(0); + EXPECT_CALL(oAcceptorBP, OnPreparePersistFail()).Times(1); + + NodeInfo oMyNode = GetMyNode(); + + ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot = BallotNumber(2, oMyNode.GetNodeID()); + + PaxosMsg oPaxosMsg; + oPaxosMsg.set_instanceid(0); + oPaxosMsg.set_nodeid(oMyNode.GetNodeID()); + oPaxosMsg.set_proposalid(3); + oPaxosMsg.set_msgtype(phxpaxos::MsgType_PaxosPrepare); + + ob.poAcceptor->OnPrepare(oPaxosMsg); + + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot == BallotNumber(3, oMyNode.GetNodeID())); +} + +TEST(Acceptor, OnAccept_Pass) +{ + AcceptorBuilder ob; + + EXPECT_CALL(ob.oMockLogStorage, Put(_,_,_,_)).WillOnce(Return(0)); + + MockAcceptorBP & oAcceptorBP = ob.oMockBreakpoint.m_oMockAcceptorBP; + EXPECT_CALL(oAcceptorBP, OnAcceptPass()).Times(1); + EXPECT_CALL(oAcceptorBP, OnAcceptPersistFail()).Times(0); + EXPECT_CALL(oAcceptorBP, OnAcceptReject()).Times(0); + + NodeInfo oMyNode = GetMyNode(); + + ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot = BallotNumber(10, oMyNode.GetNodeID()); + + PaxosMsg oPaxosMsg; + oPaxosMsg.set_instanceid(0); + oPaxosMsg.set_nodeid(oMyNode.GetNodeID()); + oPaxosMsg.set_proposalid(13); + oPaxosMsg.set_value("hello paxos"); + oPaxosMsg.set_msgtype(phxpaxos::MsgType_PaxosAccept); + + ob.poAcceptor->OnAccept(oPaxosMsg); + + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot == BallotNumber(13, oMyNode.GetNodeID())); + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oAcceptedBallot == BallotNumber(13, oMyNode.GetNodeID())); + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_sAcceptedValue == "hello paxos"); + + //second times + EXPECT_CALL(ob.oMockLogStorage, Put(_,_,_,_)).WillOnce(Return(0)); + + EXPECT_CALL(oAcceptorBP, OnAcceptPass()).Times(1); + EXPECT_CALL(oAcceptorBP, OnAcceptPersistFail()).Times(0); + EXPECT_CALL(oAcceptorBP, OnAcceptReject()).Times(0); + + oPaxosMsg.set_instanceid(0); + oPaxosMsg.set_nodeid(oMyNode.GetNodeID()); + oPaxosMsg.set_proposalid(14); + oPaxosMsg.set_value("hello hello"); + oPaxosMsg.set_msgtype(phxpaxos::MsgType_PaxosAccept); + + ob.poAcceptor->OnAccept(oPaxosMsg); + + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot == BallotNumber(14, oMyNode.GetNodeID())); + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oAcceptedBallot == BallotNumber(14, oMyNode.GetNodeID())); + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_sAcceptedValue == "hello hello"); + + //third times + EXPECT_CALL(ob.oMockLogStorage, Put(_,_,_,_)).WillOnce(Return(0)); + + EXPECT_CALL(oAcceptorBP, OnAcceptPass()).Times(1); + EXPECT_CALL(oAcceptorBP, OnAcceptPersistFail()).Times(0); + EXPECT_CALL(oAcceptorBP, OnAcceptReject()).Times(0); + + oPaxosMsg.set_instanceid(0); + oPaxosMsg.set_nodeid(oMyNode.GetNodeID()); + oPaxosMsg.set_proposalid(14); + oPaxosMsg.set_value("yes we are"); + oPaxosMsg.set_msgtype(phxpaxos::MsgType_PaxosAccept); + + ob.poAcceptor->OnAccept(oPaxosMsg); + + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot == BallotNumber(14, oMyNode.GetNodeID())); + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oAcceptedBallot == BallotNumber(14, oMyNode.GetNodeID())); + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_sAcceptedValue == "yes we are"); +} + +TEST(Acceptor, OnAccept_Reject) +{ + AcceptorBuilder ob; + + EXPECT_CALL(ob.oMockLogStorage, Put(_,_,_,_)).Times(0); + + MockAcceptorBP & oAcceptorBP = ob.oMockBreakpoint.m_oMockAcceptorBP; + EXPECT_CALL(oAcceptorBP, OnAcceptPass()).Times(0); + EXPECT_CALL(oAcceptorBP, OnAcceptPersistFail()).Times(0); + EXPECT_CALL(oAcceptorBP, OnAcceptReject()).Times(1); + + NodeInfo oMyNode = GetMyNode(); + + ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot = BallotNumber(10, oMyNode.GetNodeID()); + + PaxosMsg oPaxosMsg; + oPaxosMsg.set_instanceid(0); + oPaxosMsg.set_nodeid(oMyNode.GetNodeID()); + oPaxosMsg.set_proposalid(9); + oPaxosMsg.set_value("hello paxos"); + oPaxosMsg.set_msgtype(phxpaxos::MsgType_PaxosAccept); + + ob.poAcceptor->OnAccept(oPaxosMsg); + + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot == BallotNumber(10, oMyNode.GetNodeID())); + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oAcceptedBallot == BallotNumber(0, 0)); + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_sAcceptedValue.size() == 0); +} + +TEST(Acceptor, OnAccept_PersistFail) +{ + AcceptorBuilder ob; + + EXPECT_CALL(ob.oMockLogStorage, Put(_,_,_,_)).WillOnce(Return(-1)); + + MockAcceptorBP & oAcceptorBP = ob.oMockBreakpoint.m_oMockAcceptorBP; + EXPECT_CALL(oAcceptorBP, OnAcceptPass()).Times(0); + EXPECT_CALL(oAcceptorBP, OnAcceptPersistFail()).Times(1); + EXPECT_CALL(oAcceptorBP, OnAcceptReject()).Times(0); + + NodeInfo oMyNode = GetMyNode(); + + ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot = BallotNumber(10, oMyNode.GetNodeID()); + + PaxosMsg oPaxosMsg; + oPaxosMsg.set_instanceid(0); + oPaxosMsg.set_nodeid(oMyNode.GetNodeID()); + oPaxosMsg.set_proposalid(11); + oPaxosMsg.set_value("hello paxos"); + oPaxosMsg.set_msgtype(phxpaxos::MsgType_PaxosAccept); + + ob.poAcceptor->OnAccept(oPaxosMsg); + + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oPromiseBallot == BallotNumber(11, oMyNode.GetNodeID())); + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_oAcceptedBallot == BallotNumber(11, oMyNode.GetNodeID())); + EXPECT_TRUE(ob.poAcceptor->m_oAcceptorState.m_sAcceptedValue == "hello paxos"); +} + + diff --git a/src/ut/db_ut.cpp b/src/ut/db_ut.cpp new file mode 100644 index 000000000..7c3934683 --- /dev/null +++ b/src/ut/db_ut.cpp @@ -0,0 +1,227 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include +#include "db.h" +#include "gmock/gmock.h" + +using namespace phxpaxos; +using namespace std; +using ::testing::_; +using ::testing::Return; + +int InitDB(const int iGroupCount, MultiDatabase & oDB) +{ + string sDBPath = "./ut_test_db_path/"; + int ret = oDB.Init(sDBPath, iGroupCount); + if (ret != 0) + { + return ret; + } + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + ret = oDB.ClearAllLog(iGroupIdx); + if (ret != 0) + { + return ret; + } + } + + return 0; +} + +TEST(MultiDatabase, ClearAllLog) +{ + int iGroupCount = 2; + MultiDatabase oDB; + ASSERT_TRUE(InitDB(iGroupCount, oDB) == 0); + + const uint64_t llInstanceID = 3; + std::string sValue = "hello paxos"; + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + + ASSERT_TRUE(oDB.Put(oWriteOptions, iGroupIdx, llInstanceID, sValue) == 0); + } + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + ASSERT_TRUE(oDB.ClearAllLog(iGroupIdx) == 0); + } + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + const uint64_t llInstanceID = 3; + std::string sGetValue; + + ASSERT_TRUE(oDB.Get(iGroupIdx, llInstanceID, sGetValue) == 1); + } +} + +TEST(MultiDatabase, PUT_GET) +{ + int iGroupCount = 2; + MultiDatabase oDB; + ASSERT_TRUE(InitDB(iGroupCount, oDB) == 0); + + const uint64_t llInstanceID = 3; + std::string sValue = "hello paxos"; + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + std::string sGetValue; + ASSERT_TRUE(oDB.Get(iGroupIdx, llInstanceID, sGetValue) == 1); + } + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + + ASSERT_TRUE(oDB.Put(oWriteOptions, iGroupIdx, llInstanceID, sValue) == 0); + } + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + std::string sGetValue; + + ASSERT_TRUE(oDB.Get(iGroupIdx, llInstanceID, sGetValue) == 0); + } +} + + +TEST(MultiDatabase, Del) +{ + int iGroupCount = 2; + MultiDatabase oDB; + ASSERT_TRUE(InitDB(iGroupCount, oDB) == 0); + + const uint64_t llInstanceID = 3; + std::string sValue = "hello paxos"; + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + ASSERT_TRUE(oDB.Put(oWriteOptions, iGroupIdx, llInstanceID, sValue) == 0); + } + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + ASSERT_TRUE(oDB.Del(oWriteOptions, iGroupIdx, llInstanceID) == 0); + } + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + std::string sGetValue; + ASSERT_TRUE(oDB.Get(iGroupIdx, llInstanceID, sGetValue) == 1); + } +} + +TEST(MultiDatabase, GetMaxInstanceID) +{ + int iGroupCount = 2; + MultiDatabase oDB; + ASSERT_TRUE(InitDB(iGroupCount, oDB) == 0); + + const uint64_t llInstanceID = 3; + std::string sValue = "hello paxos"; + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + ASSERT_TRUE(oDB.Put(oWriteOptions, iGroupIdx, llInstanceID + 1, sValue) == 0); + ASSERT_TRUE(oDB.Put(oWriteOptions, iGroupIdx, llInstanceID + 3, sValue) == 0); + + uint64_t llMaxInstanceID = 0; + ASSERT_TRUE(oDB.GetMaxInstanceID(iGroupIdx, llMaxInstanceID) == 0); + EXPECT_TRUE(llMaxInstanceID == llInstanceID + 3); + } +} + +TEST(MultiDatabase, Set_Get_MinChosenInstanceID) +{ + int iGroupCount = 2; + MultiDatabase oDB; + ASSERT_TRUE(InitDB(iGroupCount, oDB) == 0); + + const uint64_t llMinChosenInstanceID = 102342342342lu; + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + ASSERT_TRUE(oDB.SetMinChosenInstanceID(oWriteOptions, iGroupIdx, llMinChosenInstanceID) == 0); + + uint64_t llGetMinChosenInstanceID = 0; + ASSERT_TRUE(oDB.GetMinChosenInstanceID(iGroupIdx, llGetMinChosenInstanceID) == 0); + + EXPECT_TRUE(llMinChosenInstanceID == llGetMinChosenInstanceID); + } +} + +TEST(MultiDatabase, Set_Get_SystemVariables) +{ + int iGroupCount = 2; + MultiDatabase oDB; + ASSERT_TRUE(InitDB(iGroupCount, oDB) == 0); + + string sBuffer = "234iskfj23io4uskfjalfj238j423j4l2k3j4lasklfjaslkfj28934j2l3j4lajflsjdlf"; + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + ASSERT_TRUE(oDB.SetSystemVariables(oWriteOptions, iGroupIdx, sBuffer) == 0); + + string sGetBuffer; + ASSERT_TRUE(oDB.GetSystemVariables(iGroupIdx, sGetBuffer) == 0); + + EXPECT_TRUE(sBuffer == sGetBuffer); + } +} + +TEST(MultiDatabase, Set_Get_MasterVariables) +{ + int iGroupCount = 2; + MultiDatabase oDB; + ASSERT_TRUE(InitDB(iGroupCount, oDB) == 0); + + string sBuffer = "234fj238j423j4l2k3j4lasklfjaslkfj28934j2l3j4lajflsjdlf"; + WriteOptions oWriteOptions; + oWriteOptions.bSync = true; + + for (int iGroupIdx = 0; iGroupIdx < iGroupCount; iGroupIdx++) + { + ASSERT_TRUE(oDB.SetMasterVariables(oWriteOptions, iGroupIdx, sBuffer) == 0); + + string sGetBuffer; + ASSERT_TRUE(oDB.GetMasterVariables(iGroupIdx, sGetBuffer) == 0); + + EXPECT_TRUE(sBuffer == sGetBuffer); + } +} + diff --git a/src/ut/make_class.cpp b/src/ut/make_class.cpp new file mode 100644 index 000000000..f4bae09cb --- /dev/null +++ b/src/ut/make_class.cpp @@ -0,0 +1,100 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "make_class.h" +#include "phxpaxos/options.h" +#include "mock_class.h" + +using ::testing::_; +using ::testing::Return; + +namespace phxpaxos +{ + +NodeInfo GetMyNode() +{ + string sIP = "127.0.0.1"; + int iPort = 11111; + + NodeInfo oMyNode(sIP, iPort); + return oMyNode; +} + +void MakeConfig(MockLogStorage * poMockLogStorage, Config *& poConfig) +{ + string sIP = "127.0.0.1"; + int iPort = 11111; + + NodeInfo oMyNode(sIP, iPort); + NodeInfoList vecNodeInfoList; + + for (int i = 0; i < 3; i++) + { + vecNodeInfoList.push_back(NodeInfo(sIP, iPort)); + iPort++; + } + + FollowerNodeInfoList vecFollowerNodeInfoList; + + int iMyGroupIdx = 0; + int iGroupCount = 1; + + poConfig = nullptr; + poConfig = new Config(poMockLogStorage, false, oMyNode, vecNodeInfoList, vecFollowerNodeInfoList, iMyGroupIdx, iGroupCount, nullptr); + assert(poConfig != nullptr); + + EXPECT_CALL(*poMockLogStorage, GetSystemVariables(_,_)).Times(1).WillOnce(Return(1)); + + poConfig->Init(); +} + +void MakeCommunicate(MockNetWork * poMockNetWork, Config * poConfig, Communicate *& poCommunicate) +{ + poCommunicate = nullptr; + poCommunicate = new Communicate(poConfig, poConfig->GetMyNodeID(), 2048, poMockNetWork); + assert(poCommunicate != nullptr); +} + +void MakeInstance(MockLogStorage * poMockLogStorage, Config * poConfig, Communicate * poCommunicate, Instance *& poInstance) +{ + poInstance = nullptr; + poInstance = new Instance(poConfig, poMockLogStorage, poCommunicate, false); + assert(poInstance != nullptr); +} + +void MakeAcceptor(MockLogStorage * poMockLogStorage, Config * poConfig, Communicate * poCommunicate, Instance * poInstance, Acceptor *& poAcceptor) +{ + poAcceptor = nullptr; + poAcceptor = new Acceptor(poConfig, poCommunicate, poInstance, poMockLogStorage); + assert(poAcceptor != nullptr); +} + +void MakeProposer(Config * poConfig, Communicate * poCommunicate, Instance * poInstance, Learner * poLearner, IOLoop * poIOLoop, Proposer *& poProposer) +{ + poProposer = nullptr; + poProposer = new Proposer(poConfig, poCommunicate, poInstance, poLearner, poIOLoop); + assert(poProposer != nullptr); +} + +} + + + diff --git a/src/ut/make_class.h b/src/ut/make_class.h new file mode 100644 index 000000000..28a171849 --- /dev/null +++ b/src/ut/make_class.h @@ -0,0 +1,46 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "config_include.h" +#include "instance.h" +#include "communicate.h" +#include "acceptor.h" +#include "proposer.h" +#include "mock_class.h" + +namespace phxpaxos +{ + +NodeInfo GetMyNode(); + +void MakeConfig(MockLogStorage * poMockLogStorage, Config *& oConfig); + +void MakeCommunicate(MockNetWork * poMockNetWork, Config * poConfig, Communicate *& poCommunicate); + +void MakeInstance(MockLogStorage * poMockLogStorage, Config * poConfig, Communicate * poCommunicate, Instance *& poInstance); + +void MakeAcceptor(MockLogStorage * poMockLogStorage, Config * poConfig, Communicate * poCommunicate, Instance * poInstance, Acceptor *& poAcceptor); + +void MakeProposer(Config * poConfig, Communicate * poCommunicate, Instance * poInstance, Learner * poLearner, IOLoop * poIOLoop, Proposer *& poProposer); + +} diff --git a/src/ut/mock_class.h b/src/ut/mock_class.h new file mode 100644 index 000000000..efcfa5ec6 --- /dev/null +++ b/src/ut/mock_class.h @@ -0,0 +1,110 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include "gmock/gmock.h" +#include "phxpaxos/network.h" +#include "phxpaxos/storage.h" +#include "phxpaxos/breakpoint.h" +#include "ioloop.h" +#include "learner.h" +#include "acceptor.h" + +class MockNetWork : public phxpaxos::NetWork +{ +public: + MOCK_METHOD0(RunNetWork, void()); + MOCK_METHOD0(StopNetWork, void()); + MOCK_METHOD3(SendMessageTCP, int(const std::string & sIp, const int iPort, const std::string & sMessage)); + MOCK_METHOD3(SendMessageUDP, int(const std::string & sIp, const int iPort, const std::string & sMessage)); +}; + +class MockLogStorage : public phxpaxos::LogStorage +{ +public: + const std::string GetLogStorageDirPath(const int iGroupIdx) { return ""; } + MOCK_METHOD3(Get, int(const int iGroupIdx, const uint64_t llInstanceID, std::string & sValue)); + MOCK_METHOD4(Put, int(const phxpaxos::WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llInstanceID, const std::string & sValue)); + MOCK_METHOD3(Del, int(const phxpaxos::WriteOptions & oWriteOptions, int iGroupIdx, const uint64_t llInstanceID)); + MOCK_METHOD2(GetMaxInstanceID, int(const int iGroupIdx, uint64_t & llInstanceID)); + MOCK_METHOD3(SetMinChosenInstanceID, int(const phxpaxos::WriteOptions & oWriteOptions, const int iGroupIdx, const uint64_t llMinInstanceID)); + MOCK_METHOD2(GetMinChosenInstanceID, int(const int iGroupIdx, uint64_t & llMinInstanceID)); + int ClearAllLog(const int iGroupIdx) { return 0; } + MOCK_METHOD3(SetSystemVariables, int(const phxpaxos::WriteOptions & oWriteOptions, const int iGroupIdx, const std::string & sBuffer)); + MOCK_METHOD2(GetSystemVariables, int(const int iGroupIdx, std::string & sBuffer)); + MOCK_METHOD3(SetMasterVariables, int(const phxpaxos::WriteOptions & oWriteOptions, const int iGroupIdx, const std::string & sBuffer)); + MOCK_METHOD2(GetMasterVariables, int(const int iGroupIdx, std::string & sBuffer)); +}; + +class MockIOLoop : public phxpaxos::IOLoop +{ +public: + MockIOLoop() : IOLoop(nullptr, nullptr) { } + //MOCK_METHOD3(AddTimer, bool(const int iTimeout, const int iType, uint32_t & iTimerID)); + //MOCK_METHOD1(RemoveTimer, void(uint32_t & iTimerID)); +}; + +class MockLearner : public phxpaxos::Learner +{ +public: + MockLearner() : Learner(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) { } + MOCK_METHOD2(ProposerSendSuccess, void(const uint64_t llLearnInstanceID, const uint64_t llProposalID)); +}; + +//////////////////////////////////////////////////// + +class MockAcceptorBP : public phxpaxos::AcceptorBP +{ +public: + MOCK_METHOD0(OnPreparePass, void()); + MOCK_METHOD0(OnPreparePersistFail, void()); + MOCK_METHOD0(OnPrepareReject, void()); + MOCK_METHOD0(OnAcceptPass, void()); + MOCK_METHOD0(OnAcceptPersistFail, void()); + MOCK_METHOD0(OnAcceptReject, void()); +}; + +class MockProposerBP : public phxpaxos::ProposerBP +{ +public: + MOCK_METHOD0(NewProposalSkipPrepare, void()); + MOCK_METHOD0(OnPrepareReplyButNotPreparing, void()); + MOCK_METHOD0(OnPrepareReplyNotSameProposalIDMsg, void()); + MOCK_METHOD1(PreparePass, void(const int iUseTimeMs)); + MOCK_METHOD0(PrepareNotPass, void()); + MOCK_METHOD0(OnAcceptReplyButNotAccepting, void()); + MOCK_METHOD0(OnAcceptReplyNotSameProposalIDMsg, void()); + MOCK_METHOD1(AcceptPass, void(const int iUseTimeMs)); + MOCK_METHOD0(AcceptNotPass, void()); +}; + +class MockBreakpoint : public phxpaxos::Breakpoint +{ +public: + phxpaxos::AcceptorBP * GetAcceptorBP() { return &m_oMockAcceptorBP; } + phxpaxos::ProposerBP * GetProposerBP() { return &m_oMockProposerBP; } + + MockAcceptorBP m_oMockAcceptorBP; + MockProposerBP m_oMockProposerBP; +}; + diff --git a/src/ut/nodeid_ut.cpp b/src/ut/nodeid_ut.cpp new file mode 100644 index 000000000..08f661bc8 --- /dev/null +++ b/src/ut/nodeid_ut.cpp @@ -0,0 +1,55 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include +#include "phxpaxos/options.h" +#include "gmock/gmock.h" + +using namespace phxpaxos; +using namespace std; +using ::testing::_; +using ::testing::Return; + +TEST(NodeID, IPPort2NodeID) +{ + string sIP = "10.123.102.77"; + int iPort = 8001; + + uint64_t llNodeID = 5577280471424835393lu; + + NodeInfo oNode(sIP, iPort); + + EXPECT_TRUE(llNodeID == oNode.GetNodeID()); +} + +TEST(NodeID, NodeID2IPPort) +{ + string sIP = "10.123.102.77"; + int iPort = 8001; + + uint64_t llNodeID = 5577280471424835393lu; + + NodeInfo oNode(llNodeID); + + EXPECT_TRUE(oNode.GetIP() == sIP); + EXPECT_TRUE(oNode.GetPort() == iPort); +} + diff --git a/src/ut/proposer_ut.cpp b/src/ut/proposer_ut.cpp new file mode 100644 index 000000000..a20a9cb83 --- /dev/null +++ b/src/ut/proposer_ut.cpp @@ -0,0 +1,300 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include +#include "gmock/gmock.h" +#include "make_class.h" +#include "mock_class.h" + +using namespace phxpaxos; +using namespace std; +using ::testing::_; +using ::testing::Return; + + +class ProposerBuilder +{ +public: + ProposerBuilder() + { + MakeConfig(&oMockLogStorage, poConfig); + MakeCommunicate(&oMockNetWork, poConfig, poCommunicate); + MakeInstance(&oMockLogStorage, poConfig, poCommunicate, poInstance); + MakeProposer(poConfig, poCommunicate, poInstance, &oMockLearner, &oMockIOLoop, poProposer); + + poProposer->SetAsTestMode(); + + BP->SetInstance(&oMockBreakpoint); + } + + ~ProposerBuilder() + { + delete poProposer; + delete poCommunicate; + delete poInstance; + delete poConfig; + BP->SetInstance(nullptr); + } + + MockNetWork oMockNetWork; + MockLogStorage oMockLogStorage; + MockIOLoop oMockIOLoop; + MockLearner oMockLearner; + + Config * poConfig; + Communicate * poCommunicate; + Instance * poInstance; + Proposer * poProposer; + + MockBreakpoint oMockBreakpoint; +}; + +TEST(Proposer, NewValue) +{ + ProposerBuilder ob; + + MockProposerBP & oProposerBP = ob.oMockBreakpoint.m_oMockProposerBP; + + ob.poProposer->m_oProposerState.m_llProposalID = 100; + string sNewValue = "hello paxos"; + + ob.poProposer->NewValue(sNewValue); + + EXPECT_TRUE(ob.poProposer->m_oProposerState.m_llProposalID == 100); + EXPECT_TRUE(ob.poProposer->m_oProposerState.m_sValue == sNewValue); + + EXPECT_TRUE(ob.poProposer->m_bIsPreparing == true); + + //second call, new ballot + + ob.poProposer->m_bWasRejectBySomeone = true; + ob.poProposer->NewValue(sNewValue); + + EXPECT_TRUE(ob.poProposer->m_oProposerState.m_llProposalID == 101); + EXPECT_TRUE(ob.poProposer->m_oProposerState.m_sValue == sNewValue); + + //third call, skip prepare + EXPECT_CALL(oProposerBP, NewProposalSkipPrepare()).Times(1); + + ob.poProposer->m_bCanSkipPrepare = true; + ob.poProposer->NewValue(sNewValue); + + EXPECT_TRUE(ob.poProposer->m_bIsAccepting == true); + EXPECT_TRUE(ob.poProposer->m_bIsPreparing == false); +} + +TEST(Proposer, OnPrepareReply_Skip) +{ + ProposerBuilder ob; + + MockProposerBP & oProposerBP = ob.oMockBreakpoint.m_oMockProposerBP; + + ob.poProposer->m_oProposerState.m_llProposalID = 100; + PaxosMsg oPaxosMsg; + + //first call + EXPECT_CALL(oProposerBP, OnPrepareReplyButNotPreparing()).Times(1); + ob.poProposer->m_bIsPreparing = false; + ob.poProposer->OnPrepareReply(oPaxosMsg); + + //second call + EXPECT_CALL(oProposerBP, OnPrepareReplyNotSameProposalIDMsg()).Times(1); + oPaxosMsg.set_proposalid(102); + ob.poProposer->m_bIsPreparing = true; + ob.poProposer->OnPrepareReply(oPaxosMsg); +} + +TEST(Proposer, OnPrepareReply_Pass) +{ + ProposerBuilder ob; + + MockProposerBP & oProposerBP = ob.oMockBreakpoint.m_oMockProposerBP; + + ob.poProposer->m_oProposerState.m_llProposalID = 100; + ob.poProposer->m_bIsPreparing = true; + ob.poProposer->m_oProposerState.m_sValue = "abc"; + PaxosMsg oPaxosMsg; + oPaxosMsg.set_proposalid(100); + + //first call + oPaxosMsg.set_preacceptid(95); + oPaxosMsg.set_preacceptnodeid(GetMyNode().GetNodeID()); + oPaxosMsg.set_nodeid(GetMyNode().GetNodeID()); + oPaxosMsg.set_value("hello paxos"); + ob.poProposer->OnPrepareReply(oPaxosMsg); + + EXPECT_TRUE(ob.poProposer->m_oProposerState.m_sValue == "hello paxos"); + + //second call + oPaxosMsg.set_rejectbypromiseid(101); + oPaxosMsg.set_nodeid(2); + ob.poProposer->OnPrepareReply(oPaxosMsg); + + //third call + oPaxosMsg.set_rejectbypromiseid(0); + oPaxosMsg.set_preacceptid(98); + oPaxosMsg.set_preacceptnodeid(3); + oPaxosMsg.set_nodeid(3); + oPaxosMsg.set_value("hello world"); + + EXPECT_CALL(oProposerBP, PreparePass(_)).Times(1); + + ob.poProposer->OnPrepareReply(oPaxosMsg); + + EXPECT_TRUE(ob.poProposer->m_bCanSkipPrepare == true); + EXPECT_TRUE(ob.poProposer->m_bIsAccepting == true); + EXPECT_TRUE(ob.poProposer->m_oProposerState.m_sValue == "hello world"); +} + +TEST(Proposer, OnPrepareReply_Reject) +{ + ProposerBuilder ob; + + MockProposerBP & oProposerBP = ob.oMockBreakpoint.m_oMockProposerBP; + + ob.poProposer->m_oProposerState.m_llProposalID = 100; + ob.poProposer->m_bIsPreparing = true; + ob.poProposer->m_oProposerState.m_sValue = "abc"; + PaxosMsg oPaxosMsg; + oPaxosMsg.set_proposalid(100); + + //first call + oPaxosMsg.set_preacceptid(95); + oPaxosMsg.set_preacceptnodeid(GetMyNode().GetNodeID()); + oPaxosMsg.set_nodeid(GetMyNode().GetNodeID()); + oPaxosMsg.set_value("hello paxos"); + ob.poProposer->OnPrepareReply(oPaxosMsg); + + EXPECT_TRUE(ob.poProposer->m_oProposerState.m_sValue == "hello paxos"); + + //second call + oPaxosMsg.set_rejectbypromiseid(101); + oPaxosMsg.set_nodeid(2); + ob.poProposer->OnPrepareReply(oPaxosMsg); + + //third call + oPaxosMsg.set_rejectbypromiseid(102); + oPaxosMsg.set_nodeid(3); + + EXPECT_CALL(oProposerBP, PrepareNotPass()).Times(1); + + ob.poProposer->OnPrepareReply(oPaxosMsg); + + EXPECT_TRUE(ob.poProposer->m_bCanSkipPrepare == false); + EXPECT_TRUE(ob.poProposer->m_bIsAccepting == false); + EXPECT_TRUE(ob.poProposer->m_oProposerState.m_sValue == "hello paxos"); +} + +TEST(Proposer, OnAcceptReply_Skip) +{ + ProposerBuilder ob; + + MockProposerBP & oProposerBP = ob.oMockBreakpoint.m_oMockProposerBP; + + ob.poProposer->m_oProposerState.m_llProposalID = 100; + PaxosMsg oPaxosMsg; + + //first call + EXPECT_CALL(oProposerBP, OnAcceptReplyButNotAccepting()).Times(1); + ob.poProposer->m_bIsAccepting = false; + ob.poProposer->OnAcceptReply(oPaxosMsg); + + //second call + EXPECT_CALL(oProposerBP, OnAcceptReplyNotSameProposalIDMsg()).Times(1); + oPaxosMsg.set_proposalid(102); + ob.poProposer->m_bIsAccepting = true; + ob.poProposer->OnAcceptReply(oPaxosMsg); +} + +TEST(Proposer, OnAcceptReply_Reject) +{ + ProposerBuilder ob; + + MockProposerBP & oProposerBP = ob.oMockBreakpoint.m_oMockProposerBP; + + ob.poProposer->m_oProposerState.m_llProposalID = 100; + ob.poProposer->m_bIsAccepting = true; + ob.poProposer->m_oProposerState.m_sValue = "abc"; + PaxosMsg oPaxosMsg; + oPaxosMsg.set_proposalid(100); + + //first call + oPaxosMsg.set_rejectbypromiseid(101); + oPaxosMsg.set_nodeid(2); + ob.poProposer->OnAcceptReply(oPaxosMsg); + + EXPECT_TRUE(ob.poProposer->m_bWasRejectBySomeone == true); + + //second call + oPaxosMsg.set_rejectbypromiseid(0); + oPaxosMsg.set_nodeid(GetMyNode().GetNodeID()); + ob.poProposer->OnAcceptReply(oPaxosMsg); + + //third call + oPaxosMsg.set_rejectbypromiseid(102); + oPaxosMsg.set_nodeid(3); + + EXPECT_CALL(oProposerBP, AcceptNotPass()).Times(1); + + ob.poProposer->OnAcceptReply(oPaxosMsg); + + EXPECT_TRUE(ob.poProposer->m_bCanSkipPrepare == false); + EXPECT_TRUE(ob.poProposer->m_oProposerState.m_sValue == "abc"); +} + +TEST(Proposer, OnAcceptReply_Pass) +{ + ProposerBuilder ob; + + MockProposerBP & oProposerBP = ob.oMockBreakpoint.m_oMockProposerBP; + + ob.poProposer->m_oProposerState.m_llProposalID = 100; + ob.poProposer->m_bIsAccepting = true; + ob.poProposer->m_oProposerState.m_sValue = "abc"; + PaxosMsg oPaxosMsg; + oPaxosMsg.set_proposalid(100); + + //first call + oPaxosMsg.set_rejectbypromiseid(0); + oPaxosMsg.set_nodeid(2); + ob.poProposer->OnAcceptReply(oPaxosMsg); + + //second call + oPaxosMsg.set_rejectbypromiseid(101); + oPaxosMsg.set_nodeid(GetMyNode().GetNodeID()); + ob.poProposer->OnAcceptReply(oPaxosMsg); + + EXPECT_TRUE(ob.poProposer->m_bWasRejectBySomeone == true); + + //third call + oPaxosMsg.set_rejectbypromiseid(0); + oPaxosMsg.set_nodeid(3); + + EXPECT_CALL(oProposerBP, AcceptPass(_)).Times(1); + EXPECT_CALL(ob.oMockLearner, ProposerSendSuccess(_,100)).Times(1); + + ob.poProposer->OnAcceptReply(oPaxosMsg); + + EXPECT_TRUE(ob.poProposer->m_bIsAccepting == false); + EXPECT_TRUE(ob.poProposer->m_bIsPreparing == false); + EXPECT_TRUE(ob.poProposer->m_oProposerState.m_sValue == "abc"); +} + diff --git a/src/ut/timer_ut.cpp b/src/ut/timer_ut.cpp new file mode 100644 index 000000000..8fd87c655 --- /dev/null +++ b/src/ut/timer_ut.cpp @@ -0,0 +1,117 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include +#include "comm_include.h" +#include +#include +#include "gmock/gmock.h" + +using namespace phxpaxos; +using namespace std; +using ::testing::_; +using ::testing::Return; + +TEST(Timer, AddTimer) +{ + Timer oTimer; + + uint64_t llAbsTime = Time::GetTimestampMS() + 30; + uint32_t iTimerID = 0; + int iType = 321; + oTimer.AddTimerWithType(llAbsTime, iType, iTimerID); + + //wait 30ms, and popout; + Time::MsSleep(35); + + uint32_t iTakeTimerID = 0; + int iTakeType = 0; + bool bHasTimeout = oTimer.PopTimeout(iTakeTimerID, iTakeType); + + EXPECT_TRUE(bHasTimeout == true); + EXPECT_TRUE(iTakeTimerID == iTimerID); + EXPECT_TRUE(iTakeType == iType); +} + +int PopTimeout(Timer & oTimer, std::map & mapTimerIDtoAbsTime, bool & bPass) +{ + bool bHasTimeout = true; + int iNextTimeout = 0; + + while(bHasTimeout) + { + uint32_t iTimerID = 0; + int iType = 0; + bHasTimeout = oTimer.PopTimeout(iTimerID, iType); + + if (bHasTimeout) + { + uint64_t llCut = mapTimerIDtoAbsTime[iTimerID] < Time::GetTimestampMS() ? + Time::GetTimestampMS() - mapTimerIDtoAbsTime[iTimerID] + : mapTimerIDtoAbsTime[iTimerID] - Time::GetTimestampMS(); + + if (llCut > 10) + { + bPass = false; + } + + iNextTimeout = oTimer.GetNextTimeout(); + + if (iNextTimeout != 0) + { + break; + } + } + + } + + return iNextTimeout; +} + +TEST(Timer, PopTimer) +{ + Timer oTimer; + + std::map mapTimerIDtoAbsTime; + + srand((unsigned int)time(NULL)); + + int iTimerObjCount = 10; + for (int i = 0; i < iTimerObjCount; i++) + { + uint64_t llAbsTime = Time::GetTimestampMS() + (OtherUtils::FastRand() % 500); + uint32_t iTimerID = 0; + + oTimer.AddTimer(llAbsTime, iTimerID); + mapTimerIDtoAbsTime[iTimerID] = llAbsTime; + } + + bool bPass = true; + int iNextTimeout = 0; + while(iNextTimeout != -1) + { + iNextTimeout = PopTimeout(oTimer, mapTimerIDtoAbsTime, bPass); + Time::MsSleep(iNextTimeout); + } + + EXPECT_TRUE(bPass == true); +} + diff --git a/src/ut/ut_main.cpp b/src/ut/ut_main.cpp new file mode 100644 index 000000000..72016be05 --- /dev/null +++ b/src/ut/ut_main.cpp @@ -0,0 +1,28 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "gmock/gmock.h" + +int main(int argc, char **argv) +{ + testing::InitGoogleMock(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/ut/wait_lock_ut.cpp b/src/ut/wait_lock_ut.cpp new file mode 100644 index 000000000..ac25a0abc --- /dev/null +++ b/src/ut/wait_lock_ut.cpp @@ -0,0 +1,131 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include +#include "comm_include.h" +#include +#include "concurrent.h" +#include "gmock/gmock.h" + +using namespace phxpaxos; +using namespace std; +using ::testing::_; +using ::testing::Return; + +class LockTester : public Thread +{ +public: + LockTester(WaitLock * poLock) + : m_poLock(poLock) + { + } + + ~LockTester() { } + + void run() + { + int iLockUseTimeMs = 0; + bool bHasLock = m_poLock->Lock(-1, iLockUseTimeMs); + ASSERT_TRUE(bHasLock == true); + int iSleepTime = 30; + Time::MsSleep(iSleepTime); + m_poLock->UnLock(); + + if (iLockUseTimeMs > 0) + { + int iCut = abs(iLockUseTimeMs - iSleepTime); + EXPECT_TRUE(iCut < 5); + } + } + +private: + WaitLock * m_poLock; +}; + +TEST(WaitLock, Lock) +{ + WaitLock oLock; + + LockTester * poTest1 = new LockTester(&oLock); + poTest1->start(); + + LockTester * poTest2 = new LockTester(&oLock); + poTest2->start(); + + poTest1->join(); + poTest2->join(); + + delete poTest1; + delete poTest2; +} + +class LockTimeoutTester : public Thread +{ +public: + LockTimeoutTester(WaitLock * poLock) + : m_poLock(poLock) + { + } + + ~LockTimeoutTester() { } + + void run() + { + int iLockUseTimeMs = 0; + int iLockTimeoutMs = 20; + bool bHasLock = m_poLock->Lock(iLockTimeoutMs, iLockUseTimeMs); + if (bHasLock) + { + EXPECT_TRUE(iLockUseTimeMs <= 1); + } + else + { + int iCut = abs(iLockTimeoutMs - iLockUseTimeMs); + EXPECT_TRUE(iCut < 5); + return; + } + + int iSleepTime = 30; + Time::MsSleep(iSleepTime); + m_poLock->UnLock(); + } + +private: + WaitLock * m_poLock; +}; + +TEST(WaitLock, LockTimeout) +{ + WaitLock oLock; + + LockTimeoutTester * poTest1 = new LockTimeoutTester(&oLock); + poTest1->start(); + + LockTimeoutTester * poTest2 = new LockTimeoutTester(&oLock); + poTest2->start(); + + poTest1->join(); + poTest2->join(); + + delete poTest1; + delete poTest2; +} + diff --git a/src/utils/Makefile.define b/src/utils/Makefile.define new file mode 100644 index 000000000..62df1831c --- /dev/null +++ b/src/utils/Makefile.define @@ -0,0 +1,31 @@ +# Tencent is pleased to support the open source community by making +# PhxPaxos available. +# Copyright (C) 2016 THL A29 Limited, a Tencent company. +# All rights reserved. +# +# Licensed under the BSD 3-Clause License (the "License"); you may +# not use this file except in compliance with the License. You may +# obtain a copy of the License at +# +# https://opensource.org/licenses/BSD-3-Clause +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# See the AUTHORS file for names of contributors. + +allobject=libutils.a + +UTILS_OBJ=concurrent.o socket.o util.o crc32.o timer.o bytes_buffer.o serial_lock.o wait_lock.o + +UTILS_LIB=utils + +UTILS_SYS_LIB=-lpthread + +UTILS_INCS=$(SRC_BASE_PATH)/src/utils + +UTILS_EXTRA_CPPFLAGS=-Wall -Werror + diff --git a/src/utils/bytes_buffer.cpp b/src/utils/bytes_buffer.cpp new file mode 100644 index 000000000..0ec3b78b6 --- /dev/null +++ b/src/utils/bytes_buffer.cpp @@ -0,0 +1,71 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "bytes_buffer.h" +#include +#include + +namespace phxpaxos +{ + +#define DEFAULT_BUFFER_LEN 1048576 + +BytesBuffer :: BytesBuffer() + : m_pcBuffer(nullptr), m_iLen(DEFAULT_BUFFER_LEN) +{ + m_pcBuffer = new char[m_iLen]; + assert(m_pcBuffer != nullptr); +} + +BytesBuffer :: ~BytesBuffer() +{ + delete m_pcBuffer; +} + +char * BytesBuffer :: GetPtr() +{ + return m_pcBuffer; +} + +int BytesBuffer :: GetLen() +{ + return m_iLen; +} + +void BytesBuffer :: Ready(const int iBufferLen) +{ + if (m_iLen < iBufferLen) + { + delete m_pcBuffer; + m_pcBuffer = nullptr; + + while (m_iLen < iBufferLen) + { + m_iLen *= 2; + } + + m_pcBuffer = new char[m_iLen]; + assert(m_pcBuffer != nullptr); + } +} + +} + diff --git a/src/utils/bytes_buffer.h b/src/utils/bytes_buffer.h new file mode 100644 index 000000000..c0aac1ac4 --- /dev/null +++ b/src/utils/bytes_buffer.h @@ -0,0 +1,44 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +namespace phxpaxos +{ + +class BytesBuffer +{ +public: + BytesBuffer(); + ~BytesBuffer(); + + char * GetPtr(); + + int GetLen(); + + void Ready(const int iBufferLen); + +private: + char * m_pcBuffer; + int m_iLen; +}; + +} diff --git a/src/utils/concurrent.cpp b/src/utils/concurrent.cpp new file mode 100644 index 000000000..cf8d91eb3 --- /dev/null +++ b/src/utils/concurrent.cpp @@ -0,0 +1,220 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "concurrent.h" +#include +#include +#include + +static void* mmThreadRun(void* p) { + phxpaxos::Thread* thread = (phxpaxos::Thread*)p; + thread->run(); + return 0; +} + +namespace phxpaxos { + +////////////////////////////////////////////////////////////////Mutex + +Mutex::Mutex() { + if (pthread_mutex_init(&_pm, 0)) { + throw SyncException(errno, "pthread_mutex_init error"); + } +} + +Mutex::~Mutex() { + pthread_mutex_destroy(&_pm); +} + +void Mutex::lock() { + int ret = pthread_mutex_lock(&_pm); + if (ret) { + throw SyncException(ret, "pthread_mutex_lock error"); + } +} + +bool Mutex::tryLock() { + int ret = pthread_mutex_trylock(&_pm); + if (ret) { + if (ret == EBUSY) { + return false; + } + throw SyncException(ret, "pthread_mutex_trylock error"); + } + return true; +} + +void Mutex::unlock() { + int ret = pthread_mutex_unlock(&_pm); + if (ret) { + throw SyncException(ret, "pthread_mutex_unlock error"); + } +} + +///////////////////////////////////////////////////////////Condition + +Condition::Condition(Mutex& mutex) : _mutex(mutex) { + if (pthread_cond_init(&_pc, 0)) { + throw SyncException(errno, "pthread_cond_init error"); + } +} + +Condition::~Condition() { + pthread_cond_destroy(&_pc); +} + +void Condition::signal() { + if (pthread_cond_signal(&_pc)) { + throw SyncException(errno, "pthread_cond_signal error"); + } +} + +void Condition::broadcast() { + if (pthread_cond_broadcast(&_pc)) { + throw SyncException(errno, "pthread_cond_broadcast error"); + } +} + +void Condition::wait() { + if (pthread_cond_wait(&_pc, &_mutex._pm)) { + throw SyncException(errno, "pthread_cond_wait error"); + } +} + +bool Condition::tryWait(int ms) { + uint64_t timeout = phxpaxos::now() + ms; + + timespec t; + t.tv_sec = (time_t)(timeout / 1000); + t.tv_nsec = (timeout % 1000) * 1000000; + + return tryWait(&t); +} + +bool Condition::tryWait(const timespec* timeout) { + int ret = pthread_cond_timedwait(&_pc, &_mutex._pm, timeout); + if (ret) { + if (ret == ETIMEDOUT) { + return false; + } + throw SyncException(errno, "pthread_cond_timedwait error"); + } + return true; +} + + +///////////////////////////////////////////////////////////ThreadAttr + +ThreadAttr::ThreadAttr() { + if (pthread_attr_init(&_attr) != 0) { + throw ThreadException("pthread_attr_init error"); + } +} + +ThreadAttr::~ThreadAttr() { + pthread_attr_destroy(&_attr); +} + +void ThreadAttr::setScope(bool sys) { + int scope = sys ? PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS; + pthread_attr_setscope(&_attr, scope); +} + +void ThreadAttr::setStackSize(size_t n) { + pthread_attr_setstacksize(&_attr, n); +} + +void ThreadAttr::setDetached(bool detached) { + int state = detached ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE; + pthread_attr_setdetachstate(&_attr, state); +} + +void ThreadAttr::setPriority(int prio) { + sched_param param; + + pthread_attr_getschedparam(&_attr, ¶m); + param.sched_priority = prio; + + pthread_attr_setschedparam(&_attr, ¶m); +} + +pthread_attr_t* ThreadAttr::impl() { + return &_attr; +} + +///////////////////////////////////////////////////////////Thread + +Thread::Thread() : _thread(0) {} + +Thread::~Thread() {} + +void Thread::start() { + int rc = pthread_create(&_thread, 0, mmThreadRun, this); + if (rc != 0) { + throw ThreadException("pthread_create error"); + } +} + +void Thread::start(ThreadAttr& attr) { + int rc = pthread_create(&_thread, attr.impl(), mmThreadRun, this); + if (rc != 0) { + throw ThreadException("pthread_create error"); + } +} + +void Thread::join() { + int rc = pthread_join(_thread, 0); + if (rc != 0) { + throw ThreadException("pthread_join error"); + } +} + +void Thread::detach() { + int rc = pthread_detach(_thread); + if (rc != 0) { + throw ThreadException("pthread_detach error"); + } +} + +pthread_t Thread::getId() const { + return _thread; +} + +void Thread::kill(int sig) { + int rc = pthread_kill(_thread, sig); + if (rc != 0) { + throw ThreadException("pthread_kill error"); + } +} + +void Thread::sleep(int ms) { + timespec t; + t.tv_sec = ms / 1000; + t.tv_nsec = (ms % 1000) * 1000000; + + int ret = 0; + do { + ret = ::nanosleep(&t, &t); + } while (ret == -1 && errno == EINTR); +} + +} + diff --git a/src/utils/concurrent.h b/src/utils/concurrent.h new file mode 100644 index 000000000..21c06fbda --- /dev/null +++ b/src/utils/concurrent.h @@ -0,0 +1,359 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "util.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 600 +#endif + +#include + +namespace phxpaxos { + +using std::deque; + +class Mutex : public Noncopyable { +public: + Mutex(); + + ~Mutex(); + + void lock(); + + bool tryLock(); + + void unlock(); + +private: + + friend class Condition; + + pthread_mutex_t _pm; +}; + +template +class ScopedLock : public Noncopyable { +public: + ScopedLock(Lock& lock, bool locked = false) : _locked(locked), _lock(lock) { + this->lock(); + } + + ~ScopedLock() { + this->unlock(); + } + + void lock() { + if (!_locked) { + _lock.lock(); + _locked = true; + } + } + + void unlock() { + if (_locked) { + _lock.unlock(); + _locked = false; + } + } + +private: + bool _locked; + Lock& _lock; +}; + +class Condition : public Noncopyable { +public: + Condition(Mutex& mutex); + + ~Condition(); + + void signal(); + + void broadcast(); + + void wait(); + + bool tryWait(const timespec* timeout); + + bool tryWait(int ms); + +private: + Mutex& _mutex; + pthread_cond_t _pc; +}; + +class ThreadAttr { +public: + ThreadAttr(); + + ~ThreadAttr(); + + void setScope(bool sys); + + void setStackSize(size_t n); + + void setDetached(bool detached); + + void setPriority(int prio); + + pthread_attr_t* impl(); + +private: + + pthread_attr_t _attr; +}; + +class Thread : public Noncopyable { +public: + Thread(); + + virtual ~Thread(); + + void start(); + + void start(ThreadAttr& attr); + + void join(); + + void detach(); + + pthread_t getId() const; + + void kill(int sig); + + virtual void run() = 0; + + static void sleep(int ms); + +protected: + pthread_t _thread; +}; + +template +class Queue : public Noncopyable { +public: + Queue() : _cond(_mutex), _size(0) {} + + virtual ~Queue() {} + + T& peek() { + while (empty()) { + _cond.wait(); + } + return _storage.front(); + } + + size_t peek(T& value) { + while (empty()) { + _cond.wait(); + } + value = _storage.front(); + return _size; + } + + bool peek(T& t, int timeoutMS) { + uint64_t timeout = phxpaxos::now() + timeoutMS; + + timespec ts; + ts.tv_sec = (time_t)(timeout / 1000); + ts.tv_nsec = (timeout % 1000) * 1000000; + while (empty()) { + if (!_cond.tryWait(&ts)) { + return false; + } + } + t = _storage.front(); + return true; + } + + size_t pop(T* values, size_t n) { + while (empty()) { + _cond.wait(); + } + + size_t i = 0; + while (!_storage.empty() && i < n) { + values[i] = _storage.front(); + _storage.pop_front(); + --_size; + ++i; + } + + return i; + } + + size_t pop() { + _storage.pop_front(); + return --_size; + } + + virtual size_t add(const T& t, bool signal = true, bool back = true) { + if (back) { + _storage.push_back(t); + } else { + _storage.push_front(t); + } + + if (signal) { + _cond.signal(); + } + + return ++_size; + } + + bool empty() const { + return _storage.empty(); + } + + size_t size() const { + return _storage.size(); + } + + void clear() { + _storage.clear(); + } + + void signal() { + _cond.signal(); + } + + void broadcast() { + _cond.broadcast(); + } + + virtual void lock() { + _mutex.lock(); + } + + virtual void unlock() { + _mutex.unlock(); + } + + void swap(Queue& q) { + _storage.swap( q._storage ); + int size = q._size; + q._size = _size; + _size = size; + } + +protected: + Mutex _mutex; + Condition _cond; + deque _storage; + size_t _size; +}; + +template , class S = std::vector > +class Heap : public Noncopyable { +public: + typedef S Storage; + typedef typename Storage::const_iterator const_iterator; + typedef typename Storage::iterator iterator; + + void push(const T& data) { + _storage.push_back(data); + std::push_heap(_storage.begin(), _storage.end(), C()); + } + + T& peek() { + return _storage.front(); + } + + void pop() { + std::pop_heap(_storage.begin(), _storage.end(), C()); + _storage.pop_back(); + } + + bool empty() const { + return _storage.empty(); + } + + size_t size() const { + return _storage.size(); + } + + void clear() { + _storage.clear(); + } + + const_iterator begin() const { + return _storage.begin(); + } + + iterator begin() { + return _storage.begin(); + } + + const_iterator end() const { + return _storage.end(); + } + + iterator end() { + return _storage.end(); + } + + void lock() { + _mutex.lock(); + } + + void unlock() { + _mutex.unlock(); + } + +private: + Storage _storage; + phxpaxos::Mutex _mutex; +}; + +class SyncException : public SysCallException { +public: + SyncException(int errCode, const string& errMsg, bool detail = true) + : SysCallException(errCode, errMsg, detail) {} + + virtual ~SyncException() throw () {} +}; + +class ThreadException : public SysCallException { +public: + ThreadException(const string& errMsg, bool detail = true) + : SysCallException(errno, errMsg, detail) {} + + virtual ~ThreadException() throw () {} +}; + +} + diff --git a/src/utils/crc32.cpp b/src/utils/crc32.cpp new file mode 100644 index 000000000..34e94c642 --- /dev/null +++ b/src/utils/crc32.cpp @@ -0,0 +1,90 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include +#include +#include "inttypes.h" + +static uint32_t crc32_tab[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +uint32_t +crc32(uint32_t crc, const uint8_t *buf, int size, int skiplen) +{ + const uint8_t *p; + + p = buf; + crc = crc ^ ~0U; + + while (size > 0) + { + crc = crc32_tab[(crc ^ *p) & 0xFF] ^ (crc >> 8); + + size -= skiplen; + p += skiplen; + } + + return crc ^ ~0U; +} + diff --git a/src/utils/crc32.h b/src/utils/crc32.h new file mode 100644 index 000000000..21124de6c --- /dev/null +++ b/src/utils/crc32.h @@ -0,0 +1,29 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#ifndef __CRC32_H__ +#define __CRC32_H__ + +#include + +uint32_t crc32(uint32_t crc, const uint8_t *buf, int len, int skiplen = 1); + +#endif diff --git a/src/utils/serial_lock.cpp b/src/utils/serial_lock.cpp new file mode 100644 index 000000000..0edfc1eb1 --- /dev/null +++ b/src/utils/serial_lock.cpp @@ -0,0 +1,68 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "serial_lock.h" +#include "util.h" + +namespace phxpaxos +{ + +SerialLock :: SerialLock() : m_oCond(m_oMutex) +{ +} + +SerialLock :: ~SerialLock() +{ +} + +void SerialLock :: Lock() +{ + m_oMutex.lock(); +} + +void SerialLock :: UnLock() +{ + m_oMutex.unlock(); +} + +void SerialLock :: Wait() +{ + m_oCond.wait(); +} + +void SerialLock :: Interupt() +{ + m_oCond.signal(); +} + +bool SerialLock :: WaitTime(const int iTimeMs) +{ + uint64_t llTimeout = Time::GetTimestampMS() + iTimeMs; + + timespec ts; + ts.tv_sec = (time_t)(llTimeout / 1000); + ts.tv_nsec = (llTimeout % 1000) * 1000000; + + return m_oCond.tryWait(&ts); +} + +} + diff --git a/src/utils/serial_lock.h b/src/utils/serial_lock.h new file mode 100644 index 000000000..72ebe90f3 --- /dev/null +++ b/src/utils/serial_lock.h @@ -0,0 +1,48 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "concurrent.h" + +namespace phxpaxos +{ + +class SerialLock +{ +public: + SerialLock(); + ~SerialLock(); + + void Lock(); + void UnLock(); + + void Wait(); + void Interupt(); + + bool WaitTime(const int iTimeMs); + +private: + Mutex m_oMutex; + Condition m_oCond; +}; + +} diff --git a/src/utils/socket.cpp b/src/utils/socket.cpp new file mode 100644 index 000000000..0a1fa5913 --- /dev/null +++ b/src/utils/socket.cpp @@ -0,0 +1,580 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "socket.h" +#include +#include +#include +#include +#include +#include + +namespace phxpaxos { + +using std::min; + +///////////////////////////////////////////////////////////SocketAddress + +SocketAddress::SocketAddress() { + _addr.addr.sa_family = AF_INET; + _addr.in.sin_port = 0; + _addr.in.sin_addr.s_addr = htonl(INADDR_NONE); +} + +SocketAddress::SocketAddress(unsigned short port) { + setAddress(port); +} + +SocketAddress::SocketAddress(const string& addr) { + setAddress(addr); +} + +SocketAddress::SocketAddress(const string& addr, unsigned short port) { + setAddress(addr, port); +} + +SocketAddress::SocketAddress(const Addr& addr) { + setAddress(addr); +} + +SocketAddress::SocketAddress(const sockaddr_in& addr) { + setAddress(addr); +} + +SocketAddress::SocketAddress(const sockaddr_un& addr) { + setAddress(addr); +} + +void SocketAddress::setAddress(unsigned short port) { + _addr.addr.sa_family = AF_INET; + _addr.in.sin_port = htons(port); + _addr.in.sin_addr.s_addr = htonl(INADDR_ANY); +} + +void SocketAddress::setAddress(const string& addr) { + string::size_type pos = addr.find_last_of(":"); + if (pos == string::npos || pos == addr.size() - 1) { + setAddress(addr, 0); + } else { + string port = addr.substr(pos + 1); + setAddress(addr.substr(0, pos), (unsigned short)atoi(port.c_str())); + } +} + +void SocketAddress::setAddress(const string& addr, unsigned short port) { + unsigned long ip = inet_addr(addr.c_str()); + if (ip == static_cast(INADDR_NONE)) { + throw SocketException("inet_addr error \"" + addr + "\""); + } + + _addr.addr.sa_family = AF_INET; + _addr.in.sin_port = htons(port); + _addr.in.sin_addr.s_addr = ip; +} + +void SocketAddress::setUnixDomain(const string& path) { + if (path.size() + 1 > sizeof(_addr.un.sun_path)) { + throw SocketException("unix domain path \"" + path + "\" too long"); + } + + _addr.addr.sa_family = AF_UNIX; + strcpy(_addr.un.sun_path, path.c_str()); +} + +unsigned long SocketAddress::getIp() const { + return _addr.in.sin_addr.s_addr; +} + +unsigned short SocketAddress::getPort() const { + return ntohs(_addr.in.sin_port); +} + +void SocketAddress::getAddress(Addr& addr) const { + memcpy(&addr, &_addr, sizeof(addr)); +} + +void SocketAddress::getAddress(sockaddr_in& addr) const { + memcpy(&addr, &_addr.in, sizeof(addr)); +} + +void SocketAddress::getAddress(sockaddr_un& addr) const { + memcpy(&addr, &_addr.un, sizeof(addr)); +} + +void SocketAddress::setAddress(const Addr& addr) { + memcpy(&_addr, &addr, sizeof(addr)); +} + +void SocketAddress::setAddress(const sockaddr_in& addr) { + memcpy(&_addr.in, &addr, sizeof(addr)); + _addr.addr.sa_family = AF_INET; +} + +void SocketAddress::setAddress(const sockaddr_un& addr) { + memcpy(&_addr.un, &addr, sizeof(addr)); +} + +int SocketAddress::getFamily() const { + return _addr.addr.sa_family; +} + +socklen_t SocketAddress::getAddressLength(const Addr& addr) { + if (addr.addr.sa_family == AF_INET) { + return sizeof(addr.in); + } else if (addr.addr.sa_family == AF_UNIX || addr.addr.sa_family == AF_LOCAL) { + return sizeof(addr.un); + } + return sizeof(addr); +} + +string SocketAddress::getHost() const { + if (_addr.addr.sa_family == AF_UNIX || _addr.addr.sa_family == AF_LOCAL) { + return _addr.un.sun_path; + } else { + char buff[16]; + + if (inet_ntop(AF_INET, &_addr.in.sin_addr, buff, sizeof(buff)) == 0) { + return string(); + } else { + return buff; + } + } +} + +string SocketAddress::toString() const { + if (_addr.addr.sa_family == AF_UNIX || _addr.addr.sa_family == AF_LOCAL) { + return _addr.un.sun_path; + } + return getHost() + ":" + str(ntohs(_addr.in.sin_port)); +} + +bool SocketAddress::operator ==(const SocketAddress& addr) const { + if (_addr.addr.sa_family != addr._addr.addr.sa_family) { + return false; + } else if (_addr.addr.sa_family == AF_UNIX || _addr.addr.sa_family == AF_LOCAL) { + return strcmp(_addr.un.sun_path, addr._addr.un.sun_path) == 0; + } else { + return _addr.in.sin_addr.s_addr == addr._addr.in.sin_addr.s_addr + && _addr.in.sin_port == addr._addr.in.sin_port; + } +} + +///////////////////////////////////////////////////////////SocketBase + +SocketBase::SocketBase() : _family(AF_INET), _handle(-1) {} + +SocketBase::SocketBase(int family, int handle) : _family(family), _handle(handle) { + if (handle == -1) { + initHandle(family); + } +} + +SocketBase::~SocketBase() { + if (_handle != -1) { + ::close(_handle); + _handle = -1; + } +} + +void SocketBase::initHandle(int family) { + _handle = ::socket(family, SOCK_STREAM, 0); + if (_handle == -1) { + throw SocketException("socket error"); + } +} + +int SocketBase::getFamily() const { + return _family; +} + +int SocketBase::getSocketHandle() const { + return _handle; +} + +void SocketBase::setSocketHandle(int handle, int family) { + if (_handle != handle) { + close(); + + _handle = handle; + _family = family; + } +} + +int SocketBase::detachSocketHandle() { + int handle = _handle; + _handle = -1; + _family = AF_INET; + return handle; +} + +bool SocketBase::getNonBlocking() const { + return getNonBlocking(_handle); +} + +void SocketBase::setNonBlocking(bool on) { + setNonBlocking(_handle, on); +} + +bool SocketBase::getNonBlocking(int fd) { + int flags = fcntl(fd, F_GETFL, 0); + return flags & O_NONBLOCK; +} + +void SocketBase::setNonBlocking(int fd, bool on) { + int flags = ::fcntl(fd, F_GETFL, 0); + + if (on) { + if (flags & O_NONBLOCK) { + return; + } + flags |= O_NONBLOCK; + } else { + if (!(flags & O_NONBLOCK)) { + return; + } + flags &= ~O_NONBLOCK; + } + + if (0 != ::fcntl(fd, F_SETFL, flags)) { + ; + } +} + +socklen_t SocketBase::getOption(int level, int option, void* value, socklen_t optLen) const { + if (::getsockopt(_handle, level, option, static_cast(value), &optLen) == -1) { + throw SocketException("getsockopt error"); + } + return optLen; +} + +void SocketBase::setOption(int level, int option, void* value, socklen_t optLen) const { + if (::setsockopt(_handle, level, option, static_cast(value), optLen) == -1) { + throw SocketException("setsockopt error"); + } +} + +void SocketBase::close() { + if (_handle != -1) { + if (::close(_handle) == -1) { + _handle = -1; + throw SocketException("close error"); + } else { + _handle = -1; + } + } +} + +void SocketBase::reset() { + close(); + initHandle(_family); +} + +///////////////////////////////////////////////////////////Socket + +const static int SOCKET_BUF_SIZE = 512; + +Socket::Socket() : SocketBase(AF_INET, -1) {} + +Socket::Socket(int handle) : SocketBase(AF_INET, handle) {} + +Socket::Socket(const SocketAddress& addr) { + connect(addr); +} + +Socket::Socket(int family, int handle) : SocketBase(family, handle) {} + +Socket::~Socket() {} + +int Socket::getSendTimeout() const { + timeval tv; + getOption(SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(timeval)); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +void Socket::setSendTimeout(int timeout) { + if (timeout >= 0) { + timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + setOption(SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + } else { + setOption(SOL_SOCKET, SO_SNDTIMEO, 0, sizeof(int)); + } +} + +int Socket::getReceiveTimeout() const { + timeval tv; + getOption(SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(timeval)); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +void Socket::setReceiveTimeout(int timeout) { + if (timeout >= 0) { + timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + setOption(SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + } else { + setOption(SOL_SOCKET, SO_RCVTIMEO, 0, sizeof(int)); + } +} + +void Socket::setSendBufferSize(int size) { + setOption(SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); +} + +void Socket::setReceiveBufferSize(int size) { + setOption(SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); +} + +void Socket::setQuickAck(bool on) { + int v = on ? 1 : 0; + setOption(IPPROTO_TCP, TCP_QUICKACK, &v, sizeof(v)); +} + +void Socket::setNoDelay(bool on) { + int v = on ? 1 : 0; + setOption(IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v)); +} + +SocketAddress Socket::getRemoteAddress() const { + return getRemoteAddress(_handle); +} + +SocketAddress Socket::getRemoteAddress(int fd) { + SocketAddress::Addr addr; + socklen_t len = sizeof(addr); + + phxpaxos::SocketAddress remoteAddr; + if (::getpeername(fd, &addr.addr, &len) == 0) { + remoteAddr.setAddress(addr); + } + + return remoteAddr; +} + +SocketAddress Socket::getLocalAddress() const { + return getLocalAddress(_handle); +} + +SocketAddress Socket::getLocalAddress(int fd) { + SocketAddress::Addr addr; + socklen_t len = sizeof(addr); + + phxpaxos::SocketAddress localAddr; + if (::getsockname(fd, &addr.addr, &len) == 0) { + localAddr.setAddress(addr); + } + + return localAddr; +} + +void Socket::connect(const SocketAddress& addr) { + SocketAddress::Addr sockAddr; + addr.getAddress(sockAddr); + + if (_handle == -1 || _family != addr.getFamily()) { + close(); + initHandle(addr.getFamily()); + } + + if (_handle < 0) { + throw SocketException("bad handle"); + } + + if (::connect(_handle, &sockAddr.addr, SocketAddress::getAddressLength(sockAddr)) == -1) { + if (errno != EINPROGRESS) { + string msg = "connect " + addr.toString() + " error"; + throw SocketException(msg); + } else if (!getNonBlocking()) { + string msg = "connect " + addr.toString() + " timeout"; + throw SocketException(msg); + } + } +} + +int Socket::send(const char* data, int dataSize, bool* again) { + const char* p = data; + int n = 0; + + if (again) { + *again = false; + } + + while (dataSize > 0) { + n = ::send(_handle, p, dataSize, 0); + if (n > 0) { + p += n; + dataSize -= n; + } else if (errno == EAGAIN) { + if (again) { + *again = true; + } + + if (!getNonBlocking()) { + throw SocketException("send timeout"); + } + + break; + } else if (errno == EINTR) { + continue; + } else { + throw SocketException("send error"); + } + } + + return p - data; +} + +int Socket::receive(char* buffer, int bufferSize, bool* again) { + char* p = buffer; + int n = 0; + + if (again) { + *again = false; + } + + while (bufferSize > 0) { + n = ::recv(_handle, p, bufferSize, 0); + if (n > 0) { + p += n; + + if (n < bufferSize) { + break; + } + + bufferSize -= n; + } else if (n == 0) { + break; + } else if (errno == EAGAIN) { + if (again) { + *again = true; + } + + if (!getNonBlocking()) { + throw SocketException("recv timeout"); + } + + break; + } else if (errno == EINTR) { + continue; + } else { + throw SocketException("recv error"); + } + } + + return p - buffer; +} + +void Socket::shutdownInput() { + if (::shutdown(_handle, SHUT_RD) == -1) { + throw SocketException("shutdown(SHUT_RD) error"); + } +} + +void Socket::shutdownOutput() { + if (::shutdown(_handle, SHUT_WR) == -1) { + throw SocketException("shutdown(SHUT_WR) error"); + } +} + +void Socket::shutdown() { + if (::shutdown(_handle, SHUT_RDWR) == -1) { + throw SocketException("shutdown error"); + } +} + +///////////////////////////////////////////////////////////ServerSocket + +ServerSocket::ServerSocket() {} + +ServerSocket::ServerSocket(const SocketAddress& addr) : SocketBase(addr.getFamily(), -1) { + listen(addr); +} + +ServerSocket::~ServerSocket() {} + +void ServerSocket::listen(const SocketAddress& addr, int backlog) { + SocketAddress::Addr localAddr; + addr.getAddress(localAddr); + + if (_handle == -1 || _family != addr.getFamily()) { + close(); + initHandle(addr.getFamily()); + } + + if (_handle < 0) { + throw SocketException("bad handle"); + } + + if (addr.getFamily() == AF_UNIX) { + ::unlink(localAddr.un.sun_path); + } else { + int reuse = 1; + setOption(SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); + } + + if (::bind(_handle, &localAddr.addr, SocketAddress::getAddressLength(localAddr)) == -1) { + throw SocketException("bind error"); + } + + if (::listen(_handle, backlog) == -1) { + throw SocketException("listen error"); + } +} + +int ServerSocket::getAcceptTimeout() const { + timeval tv; + getOption(SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(timeval)); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +void ServerSocket::setAcceptTimeout(int timeout) { + timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + setOption(SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); +} + +Socket* ServerSocket::accept() { + int fd = acceptfd(NULL); + if (fd >= 0) { + return new Socket(_family, fd); + } else { + return NULL; + } +} + +int ServerSocket::acceptfd(SocketAddress* addr) { + SocketAddress::Addr a; + socklen_t n = sizeof(a); + + int fd = ::accept(_handle, &a.addr, &n); + if (fd == -1 && (errno != EAGAIN && errno != EWOULDBLOCK)) { + throw SocketException("accept error"); + } else if (fd >= 0 && addr) { + addr->setAddress(a); + } + return fd; +} + +} + diff --git a/src/utils/socket.h b/src/utils/socket.h new file mode 100644 index 000000000..e1a3d5290 --- /dev/null +++ b/src/utils/socket.h @@ -0,0 +1,230 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "util.h" + +namespace phxpaxos { + +using std::string; + +//////////////////////////////////////////////////////////////////SocketAddress + +class SocketAddress { +public: + enum Type { + TYPE_LOOPBACK = 1, + TYPE_INNER = 2, + TYPE_OUTER = 3 + }; + + union Addr { + sockaddr addr; + sockaddr_in in; + sockaddr_un un; + }; + + SocketAddress(); + + SocketAddress(unsigned short port); + + SocketAddress(const string& addr); + + SocketAddress(const string& addr, unsigned short port); + + SocketAddress(const Addr& addr); + + SocketAddress(const sockaddr_in& addr); + + SocketAddress(const sockaddr_un& addr); + + void setAddress(unsigned short port); + + void setAddress(const string& addr); + + void setAddress(const string& addr, unsigned short port); + + void setUnixDomain(const string& path); + + unsigned long getIp() const; + + unsigned short getPort() const; + + void getAddress(Addr& addr) const; + + void getAddress(sockaddr_in& addr) const; + + void getAddress(sockaddr_un& addr) const; + + void setAddress(const Addr& addr); + + void setAddress(const sockaddr_in& addr); + + void setAddress(const sockaddr_un& addr); + + string getHost() const; + + string toString() const; + + int getFamily() const; + + static socklen_t getAddressLength(const Addr& addr); + + bool operator ==(const SocketAddress& addr) const; + + static Type getAddressType(const string& ip); + +private: + + Addr _addr; +}; + +///////////////////////////////////////////////////////////////////////Socket + +class SocketBase { +public: + SocketBase(); + + SocketBase(int family, int handle); + + virtual ~SocketBase(); + + virtual int getFamily() const; + + virtual int getSocketHandle() const; + + virtual void setSocketHandle(int handle, int family = AF_INET); + + virtual int detachSocketHandle(); + + virtual bool getNonBlocking() const; + + virtual void setNonBlocking(bool on); + + static void setNonBlocking(int fd, bool on); + + static bool getNonBlocking(int fd); + + virtual void close(); + + virtual void reset(); + +protected: + + void initHandle(int family); + + socklen_t getOption(int level, int option, void* value, socklen_t optLen) const; + + void setOption(int level, int option, void* value, socklen_t optLen) const; + + int _family; + int _handle; +}; + +class Socket : public SocketBase { +public: + Socket(); + + Socket(const SocketAddress& addr); + + Socket(int handle); + + Socket(int family, int handle); + + virtual ~Socket(); + + int getSendTimeout() const; + + void setSendTimeout(int timeout); + + int getReceiveTimeout() const; + + void setReceiveTimeout(int timeout); + + void setSendBufferSize(int size); + + void setReceiveBufferSize(int size); + + void setQuickAck(bool on); + + void setNoDelay(bool on); + + SocketAddress getRemoteAddress() const; + + static SocketAddress getRemoteAddress(int fd); + + SocketAddress getLocalAddress() const; + + static SocketAddress getLocalAddress(int fd); + + virtual void connect(const SocketAddress& addr); + + virtual int send(const char* data, int dataSize, bool* again = 0); + + virtual int receive(char* buffer, int bufferSize, bool* again = 0); + + virtual void shutdownInput(); + + virtual void shutdownOutput(); + + virtual void shutdown(); +}; + +///////////////////////////////////////////////////////////////////////ServerSocket + +class ServerSocket : public SocketBase { +public: + ServerSocket(); + + ServerSocket(const SocketAddress& addr); + + virtual ~ServerSocket(); + + int getAcceptTimeout() const; + + void setAcceptTimeout(int timeout); + + virtual void listen(const SocketAddress& addr, int backlog = SOMAXCONN); + + virtual Socket* accept(); + + virtual int acceptfd(SocketAddress* addr); +}; + +///////////////////////////////////////////////////////////////////////SocketException + +class SocketException : public SysCallException { +public: + SocketException(const string& errMsg, bool detail = true) + : SysCallException(errno, errMsg, detail) {} + + virtual ~SocketException() throw () {} +}; + +} + diff --git a/src/utils/timer.cpp b/src/utils/timer.cpp new file mode 100644 index 000000000..6dc6c72e1 --- /dev/null +++ b/src/utils/timer.cpp @@ -0,0 +1,94 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "timer.h" +#include "util.h" +#include + +namespace phxpaxos +{ + +Timer :: Timer() : m_iNowTimerID(1) +{ +} + +Timer :: ~Timer() +{ +} + +void Timer :: AddTimer(const uint64_t llAbsTime, uint32_t & iTimerID) +{ + return AddTimerWithType(llAbsTime, 0, iTimerID); +} + +void Timer :: AddTimerWithType(const uint64_t llAbsTime, const int iType, uint32_t & iTimerID) +{ + iTimerID = m_iNowTimerID++; + + TimerObj tObj(iTimerID, llAbsTime, iType); + m_vecTimerHeap.push_back(tObj); + push_heap(begin(m_vecTimerHeap), end(m_vecTimerHeap)); +} + +const int Timer :: GetNextTimeout() const +{ + if (m_vecTimerHeap.empty()) + { + return -1; + } + + int iNextTimeout = 0; + + TimerObj tObj = m_vecTimerHeap.front(); + uint64_t llNowTime = Time::GetTimestampMS(); + if (tObj.m_llAbsTime > llNowTime) + { + iNextTimeout = (int)(tObj.m_llAbsTime - llNowTime); + } + + return iNextTimeout; +} + +bool Timer :: PopTimeout(uint32_t & iTimerID, int & iType) +{ + if (m_vecTimerHeap.empty()) + { + return false; + } + + TimerObj tObj = m_vecTimerHeap.front(); + uint64_t llNowTime = Time::GetTimestampMS(); + if (tObj.m_llAbsTime > llNowTime) + { + return false; + } + + pop_heap(begin(m_vecTimerHeap), end(m_vecTimerHeap)); + m_vecTimerHeap.pop_back(); + + iTimerID = tObj.m_iTimerID; + iType = tObj.m_iType; + + return true; +} + +} + diff --git a/src/utils/timer.h b/src/utils/timer.h new file mode 100644 index 000000000..134368e4b --- /dev/null +++ b/src/utils/timer.h @@ -0,0 +1,72 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include + +namespace phxpaxos +{ + +class Timer +{ +public: + Timer(); + ~Timer(); + + void AddTimer(const uint64_t llAbsTime, uint32_t & iTimerID); + + void AddTimerWithType(const uint64_t llAbsTime, const int iType, uint32_t & iTimerID); + + bool PopTimeout(uint32_t & iTimerID, int & iType); + + const int GetNextTimeout() const; + +private: + struct TimerObj + { + TimerObj(uint32_t iTimerID, uint64_t llAbsTime, int iType) + : m_iTimerID(iTimerID), m_llAbsTime(llAbsTime), m_iType(iType) {} + + uint32_t m_iTimerID; + uint64_t m_llAbsTime; + int m_iType; + + bool operator < (const TimerObj & obj) const + { + if (obj.m_llAbsTime == m_llAbsTime) + { + return obj.m_iTimerID < m_iTimerID; + } + else + { + return obj.m_llAbsTime < m_llAbsTime; + } + } + }; + +private: + uint32_t m_iNowTimerID; + std::vector m_vecTimerHeap; +}; + +} diff --git a/src/utils/util.cpp b/src/utils/util.cpp new file mode 100644 index 000000000..4ced96be3 --- /dev/null +++ b/src/utils/util.cpp @@ -0,0 +1,282 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "util.h" +#include +#include +#include +#include +#include +#include +#include + +namespace phxpaxos { + +uint64_t now() { + timeval tv; + gettimeofday(&tv, 0); + return (uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000; +} + +const uint64_t Time :: GetTimestampMS() +{ + uint64_t llNow; + struct timeval tv; + + gettimeofday(&tv, NULL); + + llNow = tv.tv_sec; + llNow *= 1000; + llNow += tv.tv_usec / 1000; + + return llNow; +} + +void Time :: MsSleep(const int iTimeMs) +{ + timespec t; + t.tv_sec = iTimeMs / 1000; + t.tv_nsec = (iTimeMs % 1000) * 1000000; + + int ret = 0; + do + { + ret = ::nanosleep(&t, &t); + } while (ret == -1 && errno == EINTR); +} + +///////////////////////////////////////////// +int FileUtils :: IsDir(const std::string & sPath, bool & bIsDir) +{ + bIsDir = false; + struct stat tStat; + int ret = stat(sPath.c_str(), &tStat); + if (ret != 0) + { + return ret; + } + + if (tStat.st_mode & S_IFDIR) + { + bIsDir = true; + } + + return 0; +} + +int FileUtils :: DeleteDir(const std::string & sDirPath) +{ + DIR * dir = nullptr; + struct dirent * ptr; + + dir = opendir(sDirPath.c_str()); + if (dir == nullptr) + { + return -1; + } + + + int ret = 0; + while ((ptr = readdir(dir)) != nullptr) + { + if (strcmp(ptr->d_name, ".") == 0 + || strcmp(ptr->d_name, "..") == 0) + { + continue; + } + + char sChildPath[1024] = {0}; + snprintf(sChildPath, sizeof(sChildPath), "%s/%s", sDirPath.c_str(), ptr->d_name); + + bool bIsDir = false; + ret = FileUtils::IsDir(sChildPath, bIsDir); + if (ret != 0) + { + break; + } + + if (bIsDir) + { + ret = DeleteDir(sChildPath); + if (ret != 0) + { + break; + } + } + else + { + ret = remove(sChildPath); + if (ret != 0) + { + break; + } + } + } + + closedir(dir); + + if (ret == 0) + { + ret = remove(sDirPath.c_str()); + } + + return ret; +} + +int FileUtils :: IterDir(const std::string & sDirPath, std::vector & vecFilePathList) +{ + DIR * dir = nullptr; + struct dirent * ptr; + + dir = opendir(sDirPath.c_str()); + if (dir == nullptr) + { + return 0; + } + + + int ret = 0; + while ((ptr = readdir(dir)) != nullptr) + { + if (strcmp(ptr->d_name, ".") == 0 + || strcmp(ptr->d_name, "..") == 0) + { + continue; + } + + char sChildPath[1024] = {0}; + snprintf(sChildPath, sizeof(sChildPath), "%s/%s", sDirPath.c_str(), ptr->d_name); + + bool bIsDir = false; + ret = FileUtils::IsDir(sChildPath, bIsDir); + if (ret != 0) + { + break; + } + + if (bIsDir) + { + ret = IterDir(sChildPath, vecFilePathList); + if (ret != 0) + { + break; + } + } + else + { + vecFilePathList.push_back(sChildPath); + } + } + + closedir(dir); + + return ret; +} + +//////////////////////////////// + +TimeStat :: TimeStat() +{ + m_llTime = 0; +} + +int TimeStat :: Point() +{ + uint64_t llNowTime = Time::GetTimestampMS(); + int llPassTime = 0; + if (llNowTime > m_llTime) + { + llPassTime = llNowTime - m_llTime; + } + + m_llTime = llNowTime; + + return llPassTime; +} + +///////////////////////////////// + +uint64_t OtherUtils :: GenGid(const uint64_t llNodeID) +{ + return (llNodeID ^ FastRand()) + FastRand(); +} + +////////////////////////////////////////////////////////// + +#ifdef __i386 + +__inline__ uint64_t rdtsc() +{ + uint64_t x; + __asm__ volatile ("rdtsc" : "=A" (x)); + return x; +} + +#elif __amd64 + +__inline__ uint64_t rdtsc() +{ + + uint64_t a, d; + __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); + return (d<<32) | a; +} + +#endif + +struct FastRandomSeed { + bool init; + unsigned int seed; +}; + +static __thread FastRandomSeed seed_thread_safe = { false, 0 }; + +static void ResetFastRandomSeed() +{ + seed_thread_safe.seed = rdtsc(); + seed_thread_safe.init = true; +} + +static void InitFastRandomSeedAtFork() +{ + pthread_atfork(ResetFastRandomSeed, ResetFastRandomSeed, ResetFastRandomSeed); +} + +static void InitFastRandomSeed() +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, InitFastRandomSeedAtFork); + + ResetFastRandomSeed(); +} + +const uint32_t OtherUtils :: FastRand() +{ + if (!seed_thread_safe.init) + { + InitFastRandomSeed(); + } + + return rand_r(&seed_thread_safe.seed); +} + +} + diff --git a/src/utils/util.h b/src/utils/util.h new file mode 100644 index 000000000..81caf91e6 --- /dev/null +++ b/src/utils/util.h @@ -0,0 +1,125 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace phxpaxos { + +using std::string; +using std::exception; +using std::ostringstream; + +template +string str(const T& t) { + ostringstream os; + os << t; + return os.str(); +} + +uint64_t now(); + +class SysCallException : public exception { +public: + SysCallException(int errCode, const string& errMsg, bool detail = true) : _errCode(errCode), _errMsg(errMsg) { + if (detail) { + _errMsg.append(", ").append(::strerror(errCode)); + } + } + + virtual ~SysCallException() throw () {} + + int getErrorCode() const throw () { + return _errCode; + } + + const char* what() const throw () { + return _errMsg.c_str(); + } + +protected: + int _errCode; + string _errMsg; +}; + +class Noncopyable { +protected: + Noncopyable() {} + ~Noncopyable() {} +private: + Noncopyable(const Noncopyable&); + const Noncopyable& operator=(const Noncopyable&); +}; + +/////////////////////////////////////////////////////////////// + +class Time +{ +public: + static const uint64_t GetTimestampMS(); + + static void MsSleep(const int iTimeMs); +}; + +class FileUtils +{ +public: + static int IsDir(const std::string & sPath, bool & bIsDir); + + static int DeleteDir(const std::string & sDirPath); + + static int IterDir(const std::string & sDirPath, std::vector & vecFilePathList); +}; + +class TimeStat +{ +public: + TimeStat(); + + int Point(); +private: + uint64_t m_llTime; +}; + +class OtherUtils +{ +public: + static uint64_t GenGid(const uint64_t llNodeID); + + static const uint32_t FastRand(); +}; + + +} diff --git a/src/utils/utils_include.h b/src/utils/utils_include.h new file mode 100644 index 000000000..a7756dd26 --- /dev/null +++ b/src/utils/utils_include.h @@ -0,0 +1,31 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "./concurrent.h" +#include "./socket.h" +#include "./util.h" +#include "./crc32.h" +#include "./timer.h" +#include "./serial_lock.h" +#include "./wait_lock.h" +#include "./bytes_buffer.h" diff --git a/src/utils/wait_lock.cpp b/src/utils/wait_lock.cpp new file mode 100644 index 000000000..03b2cc7d8 --- /dev/null +++ b/src/utils/wait_lock.cpp @@ -0,0 +1,80 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#include "wait_lock.h" + +namespace phxpaxos +{ + +WaitLock :: WaitLock() : m_bIsLockUsing(false) +{ +} + +WaitLock :: ~WaitLock() +{ +} + +bool WaitLock :: Lock(const int iTimeoutMs, int & iUseTimeMs) +{ + uint64_t llBeginTime = Time::GetTimestampMS(); + + m_oSerialLock.Lock(); + + while (m_bIsLockUsing) + { + if (iTimeoutMs == -1) + { + m_oSerialLock.Wait(); + } + else + { + if (!m_oSerialLock.WaitTime(iTimeoutMs)) + { + //lock timeout + iUseTimeMs = iTimeoutMs; + m_oSerialLock.UnLock(); + + return false; + } + } + } + + m_bIsLockUsing = true; + m_oSerialLock.UnLock(); + + uint64_t llEndTime = Time::GetTimestampMS(); + iUseTimeMs = llEndTime > llBeginTime ? (int)(llEndTime - llBeginTime) : 0; + + return true; +} + +void WaitLock :: UnLock() +{ + m_oSerialLock.Lock(); + + m_bIsLockUsing = false; + m_oSerialLock.Interupt(); + + m_oSerialLock.UnLock(); +} + +} + diff --git a/src/utils/wait_lock.h b/src/utils/wait_lock.h new file mode 100644 index 000000000..ad2fcb59b --- /dev/null +++ b/src/utils/wait_lock.h @@ -0,0 +1,44 @@ +/* +Tencent is pleased to support the open source community by making +PhxPaxos available. +Copyright (C) 2016 THL A29 Limited, a Tencent company. +All rights reserved. + +Licensed under the BSD 3-Clause License (the "License"); you may +not use this file except in compliance with the License. You may +obtain a copy of the License at + +https://opensource.org/licenses/BSD-3-Clause + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied. See the License for the specific language governing +permissions and limitations under the License. + +See the AUTHORS file for names of contributors. +*/ + +#pragma once + +#include "serial_lock.h" + +namespace phxpaxos +{ + +class WaitLock +{ +public: + WaitLock(); + ~WaitLock(); + + bool Lock(const int iTimeoutMs, int & iUseTimeMs); + + void UnLock(); + +private: + SerialLock m_oSerialLock; + bool m_bIsLockUsing; +}; + +} diff --git a/src_list b/src_list new file mode 100644 index 000000000..72eafd04a --- /dev/null +++ b/src_list @@ -0,0 +1 @@ +src plugin include sample diff --git a/tools/build_comm.py b/tools/build_comm.py new file mode 100644 index 000000000..9040df45e --- /dev/null +++ b/tools/build_comm.py @@ -0,0 +1,15 @@ +import os +import sys + +include_makefile_name="Makefile.define" +user_home = os.path.expanduser('~') + +def GetLableName( name, suffix ): + return name.upper()+"_"+suffix + +def GetLibName( name ): + return "lib"+name+".a" + +def GetELibName( name ): + return "elib"+name+".a" + diff --git a/tools/build_comm.pyc b/tools/build_comm.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6ca2619303ed5effd53c2254161505e01b0aa3e GIT binary patch literal 862 zcmcJN%}T>S5XUD;n||0L6r`_^Q-dg;L(A_`_#Y=rZU&Ff( zpflTQ&!R5b+5djb)ihuVO+8FCxDqa`jg6gNK-aV)1`p&@ZcpdK( 1): + u_list.remove(item) + return u_list + +res_list={} +makefile=None +makefile_name = "Makefile" + +def GetSourceTagFromDeps(path, lib_name, tag_name): + define_name = GetLableName(lib_name, tag_name) + + lib_define_name = GetLableName(lib_name, "LIB") + res = [] + + if(path.find("third_party") >=0): + return res + + if((path,lib_name,tag_name) in res_list): + return res_list[ (path,lib_name,tag_name) ] + + if( tag_name == "FULL_LIB_DEPS_PATH" ): + res.append( "$(SRC_BASE_PATH)/%s" % path ) + + lib_path = base_path + "/" + path + "/" + include_makefile_name + makefile_file = open(lib_path, "r") + try: + lines = makefile_file.readlines() + for line in lines: + values=line.split('=') + if(values[0] == define_name): + value = values[1].replace('\n', '').split(' ') + for obj in value: + if(len(obj) > 0): + if(tag_name == "OBJ"): + res.append("%s/%s" % (path, obj)) + elif(tag_name == "LIB"): + if(len(obj.split(':')) == 1): + res.append(obj) + else: + res.append(obj) + + if(values[0] == lib_define_name): + res_inc = values[1].replace('\n','') + dep_lib_list = res_inc.split(' ') + for dep_lib in dep_lib_list: + if(len(dep_lib.split(':')) > 1): + deps_path = dep_lib.split(':')[0] + deps_lib_name = dep_lib.split(':')[1] + if(deps_path == ""): + deps_path = path + res+=GetSourceTagFromDeps(deps_path, deps_lib_name, tag_name) + + finally: + makefile_file.close() + res=Uniq(res) + res_list[ (path,lib_name,tag_name) ] = res + return res + + +def PrintComm(path, target_name, lib_name): + inc_res=GetSourceTagFromDeps(path, lib_name, "INCS") + cppflags_res=GetSourceTagFromDeps(path, lib_name, "EXTRA_CPPFLAGS") + full_lib_path_res=GetSourceTagFromDeps(path, lib_name, "FULL_LIB_DEPS_PATH") + + obj_name = "%s_%s" % (lib_name.upper(), "SRC") + inc_name = "%s_%s" % (lib_name.upper(), "INCS") + full_lib_path_name = "%s_%s" % (lib_name.upper(), "FULL_LIB_PATH") + extra_cpp_flag_name = "%s_%s" % (lib_name.upper(), "EXTRA_CPPFLAGS") + + makefile.write("%s=$(%s)\n" % (obj_name, GetLableName(lib_name, "OBJ"))) + makefile.write("%s=$(sort %s)\n" % (inc_name, ' '.join(inc_res))) + makefile.write("%s=$(sort %s)\n" % (full_lib_path_name, ' '.join(full_lib_path_res))) + makefile.write("%s=%s\n\n" % (extra_cpp_flag_name,' '.join(cppflags_res))) + + makefile.write("CPPFLAGS+=$(patsubst %%,-I%%, $(%s))\n" % inc_name) + makefile.write("CPPFLAGS+=$(%s)\n\n" % extra_cpp_flag_name) + + return (obj_name,inc_name, full_lib_path_name, extra_cpp_flag_name) + +def PrintReferenceDIR(target_name, direct_inc_name): + makefile.write("%s_dir:$(%s)\n" % (target_name, direct_inc_name)) + makefile.write("\t@for dir in $^;\\\n") + makefile.write("\tdo \\\n") + makefile.write("\tcurrent_dir=`readlink $$dir -m`;\\\n"); + makefile.write("\tpwd_dir=`pwd`;\\\n"); + makefile.write("\tpwd_dir=`readlink $$pwd_dir -m`;\\\n"); + makefile.write("\tis_3rd_dir=`echo $$dir | grep -v third_party`;\\\n"); + makefile.write("\tif ([ \"$$current_dir\" != \"$$pwd_dir\" ] && [ \"$$is_3rd_dir\" != \"\" ]); then \\\n"); + makefile.write("\tmake -C $$dir;\\\n"); + makefile.write("\tfi;\\\n"); + makefile.write("\tdone\n\n"); + + +def PrintLib(path, target_name, lib_name, export = False): + (obj_name,inc_name, direct_inc_name, extra_cpp_flag_name) = PrintComm(path, target_name, lib_name) + + if(export == True): + makefile.write("lib_%s: %s_dir %s/lib%s.a %s/lib%s.a\n\n" % (target_name, target_name, lib_path, target_name, ext_lib_path, target_name)) + clean_dir.append( "%s/lib%s.a" % (lib_path, target_name)) + clean_dir.append( "%s/lib%s.a" % (ext_lib_path, target_name)) + + PrintReferenceDIR(target_name, direct_inc_name) + + src_name = GetLableName(lib_name, "LIB_OBJ") + + makefile.write("%s/lib%s.a: $(%s)\n" % (lib_path, target_name, obj_name)) + makefile.write("\tar -cvq $@ $(%s)\n\n" % (obj_name)) + + src_res=GetSourceTagFromDeps(path, lib_name, "OBJ") + makefile.write("%s=$(patsubst %%, $(SRC_BASE_PATH)/%%, %s)\n" % (src_name, ' '.join(src_res))) + makefile.write("%s/lib%s.a: $(%s)\n" % (ext_lib_path, target_name, src_name)) + makefile.write("\tar -cvq $@ $(%s)\n\n" % (src_name)) + + else: + makefile.write("lib_%s:%s/lib%s.a\n\n" % (target_name, lib_path, target_name)) + clean_dir.append( "%s/lib%s.a" % (lib_path, target_name)) + + makefile.write("%s/lib%s.a: $(%s)\n" % (lib_path, target_name, obj_name)) + makefile.write("\tar -cvq $@ $(%s)\n\n" % (obj_name)) + +def PrintBin(path, target_name, lib_name): + + (obj_name,inc_name, direct_inc_name, extra_cpp_flag_name) = PrintComm(path, target_name, lib_name) + + link_name = "%s_%s" % (lib_name.upper(), "LINK") + sys_lib_name = "%s_%s" % (lib_name.upper(), "SYS_LIB") + + link_res=GetSourceTagFromDeps(path, lib_name, "LIB") + sys_lib_res=GetSourceTagFromDeps(path, lib_name, "SYS_LIB") + + makefile.write("%s=%s\n" % (link_name, ' '.join(link_res))) + makefile.write("%s=%s\n" % (sys_lib_name,' '.join(sys_lib_res))) + + flag_key = GetLableName(lib_name, "FLAGS") + makefile.write("%s+=$(LDFLAGS)\n\n" % flag_key) + makefile.write("%s+=$(patsubst %%,-l%%, $(%s))\n" % (flag_key, link_name)) + makefile.write("%s+=$(%s)\n" % (flag_key, sys_lib_name)) + + makefile.write("%s_bin:%s_dir %s\n\n" % (target_name, target_name, target_name)) + + PrintReferenceDIR(target_name, direct_inc_name) + + makefile.write("%s:$(%s)\n" % (target_name, obj_name)) + makefile.write("\t$(CXX) $^ -o $@ $(%s)\n" % flag_key) + makefile.write("\tcp $@ %s/\n\n" % sbin_path) + clean_dir.append("%s" % target_name ) + clean_dir.append("%s/%s" % (sbin_path, target_name)) + +def GetSubDirList(path): + sub_dir_list=[] + + if( os.path.exists("%s/src_list" % path ) ): + sub_dir_file=open("%s/src_list" % path) + lines = sub_dir_file.readlines() + for sub_dir in lines: + sub_dir_list.append(sub_dir.strip()) + sub_dir_file.close() + else: + sub_dir=os.listdir(path) + for dir in sub_dir: + if( os.path.isdir( "%s/%s" % ( path, dir ) ) and dir[0] != "." ): + sub_dir_list.append( dir ) + return sub_dir_list + +def PrintMakeAllSubDir(dir_list): + + if( len(dir_list) > 0 ): + makefile.write( "SUBDIRS=%s\n\n" % ' '.join(dir_list) ) + + makefile.write( ".PHONY:sub_dir\n" ); + makefile.write( "sub_dir:$(SUBDIRS)\n" ); + makefile.write("\t@for sub_dir in $^; do \\\n"); + makefile.write("\tmake -C $$sub_dir; \\\n"); + makefile.write("\tdone\n\n"); + + makefile.write( ".PHONY:clean\n" ) + makefile.write( "clean:$(SUBDIRS)\n" ) + makefile.write("\t@for sub_dir in $^; do \\\n") + makefile.write("\tmake -C $$sub_dir clean;\\\n") + makefile.write("\tdone\n") + makefile.write("\trm -rf *.o %s " % ' '.join(clean_dir)); + else: + makefile.write("clean:\n") + makefile.write("\trm -rf *.o %s " % ' '.join(clean_dir)); + +def CreateMySQL(): + percona_path=base_path+"/percona"; + makefile.write( ".PHONY:mysql\n" ); + makefile.write( "mysql:\n" ); +#makefile.write("\tcd percona;\\\n"); +#makefile.write("\tcmake percona -DCMAKE_INSTALL_PREFIX=%s -DMYSQL_DATADIR=%s -DSYSCONFDIR=%s;\n" +# % (percona_path,percona_path, percona_path ) ); + makefile.write("\tmake -C percona;\n"); + + +def Process(path, library_list, elibrary_list, binary_list): + for lib in library_list: + if(len(lib) == 0): + continue + PrintLib(path, lib, lib) + + for lib in elibrary_list: + if(len(lib) == 0): + continue + PrintLib(path, lib, lib, True) + + for lib in binary_list: + if(len(lib) == 0): + continue + PrintBin(path, lib, lib) + + +def CreateMakeFile(path): + + global makefile + global base_path + + target_list = [] + library_list = [] + elibrary_list = [] + binary_list = [] + + lib_count = 0 + + makefile_define_path = "%s/%s" % (path, include_makefile_name) + makefile_path = "%s/%s" % (path, makefile_name) + + makefile = open(makefile_path, "w"); + makefile.write("SRC_BASE_PATH=%s\n\n" % base_path) + if(os.path.exists(makefile_define_path)): + define_makefile_file = open(makefile_define_path) + try: + lines = define_makefile_file.readlines() + for line in lines: + args = line.split('=') + if(len(args) > 1 and args[0] == "allobject"): + target_list = str.strip(args[1]).split(' ') + + for target in target_list: + if(len(target) == 0): + continue + lib_count = lib_count+1 + if(target[0:3] == "lib"): + library_list.append(target[3:-2]) + elif(target[0:4] == "elib"): + elibrary_list.append(target[4:-2]) + else: + binary_list.append(target) + + except: + print "file %s not found:" % makefile_define_path + finally: + define_makefile_file.close() + + makefile.write("all:"); + if( lib_count > 0 ): + for lib in library_list: + makefile.write("lib_%s " %(lib)); + + for lib in elibrary_list: + makefile.write("lib_%s " %(lib)); + + for lib in binary_list: + makefile.write("%s_bin " %(lib)); + else: + makefile.write("sub_dir"); + makefile.write("\n\n"); + + makefile.write("include $(SRC_BASE_PATH)/makefile.mk\n\n" ) + if( lib_count > 0 ): + makefile.write("include %s\n" % include_makefile_name) + Process(path[len(base_path):], library_list, elibrary_list, binary_list) + + if( path != base_path ): + sub_dir_list = GetSubDirList(path) + PrintMakeAllSubDir(sub_dir_list) + else: + PrintMakeAllSubDir([]) + + for target in elibrary_list: + makefile.write("lib%s.a %s/lib%s.a " % (target, lib_path,target)); + for target in binary_list: + makefile.write("%s " % (target)); + makefile.write("\n\n"); + else: + sub_dir_list = GetSubDirList(path) + PrintMakeAllSubDir(sub_dir_list) + + makefile.close() + + current_dir=os.path.abspath(".") + + +if(__name__ == '__main__'): + base_path = sys.argv[1] + current_path = sys.argv[2] + if(current_path[0:len(base_path)] != base_path): + print "path error, base %s, current %s" % (base_path, current_path[0:len(base_path)]) + exit(0) + CreateMakeFile(current_path)