diff --git a/.github/workflows/pikiwidb.yml b/.github/workflows/pikiwidb.yml index ce822fcff..3d86d9466 100644 --- a/.github/workflows/pikiwidb.yml +++ b/.github/workflows/pikiwidb.yml @@ -3,6 +3,7 @@ name: Pikiwidb on: push: pull_request: + branches: [ "unstable" ] jobs: build_on_macos: @@ -13,4 +14,19 @@ jobs: - name: Build run: | - sh build.sh \ No newline at end of file + sh build.sh + + build_on_ubuntu: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: | + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + + - name: Check Format + working-directory: ${{ github.workspace }}/build + run: make check-format diff --git a/CMakeLists.txt b/CMakeLists.txt index c6ada246d..d697e40ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,12 @@ ADD_CUSTOM_TARGET(format --quiet --fix ) +ADD_CUSTOM_TARGET(check-format + COMMAND ${BUILD_SUPPORT_DIR}/run_clang_format.py + /usr/bin/clang-format + ${BUILD_SUPPORT_DIR}/clang_format_exclusions.txt + --source_dirs ${FORMAT_DIRS} +) ADD_CUSTOM_TARGET(clang-tidy COMMAND ${BUILD_SUPPORT_DIR}/run_clang_tidy.py diff --git a/build_support/run_clang_format.py b/build_support/run_clang_format.py index 49ca86b18..fcc43072d 100755 --- a/build_support/run_clang_format.py +++ b/build_support/run_clang_format.py @@ -34,7 +34,7 @@ def check(arguments, source_dir): fullpaths = (os.path.join(directory, filename) for filename in filenames) source_files = [x for x in fullpaths - if x.endswith(".h") or x.endswith(".cpp")] + if x.endswith(".h") or x.endswith(".cpp") or x.endswith(".cc") or x.endswith(".c")] formatted_filenames.extend( # Filter out files that match the globs in the globs file [filename for filename in source_files diff --git a/src/base_cmd.cc b/src/base_cmd.cc index 3affcadb1..e4a0369b6 100644 --- a/src/base_cmd.cc +++ b/src/base_cmd.cc @@ -26,9 +26,7 @@ bool BaseCmd::CheckArg(size_t num) const { return num >= -arity_; } -std::vector BaseCmd::CurrentKey(PClient* client) const { - return std::vector{client->Key()}; -} +std::vector BaseCmd::CurrentKey(PClient* client) const { return std::vector{client->Key()}; } void BaseCmd::Execute(PClient* client) { if (!DoInitial(client)) { diff --git a/src/base_cmd.h b/src/base_cmd.h index f387112e1..ad61345ab 100644 --- a/src/base_cmd.h +++ b/src/base_cmd.h @@ -43,7 +43,6 @@ const std::string kCmdNameBitCount = "bitcount"; const std::string kCmdNameAuth = "auth"; - enum CmdFlags { CmdFlagsWrite = (1 << 0), // May modify the dataset CmdFlagsReadonly = (1 << 1), // Doesn't modify the dataset diff --git a/src/client.cc b/src/client.cc index 6eeaa11f7..f388bf972 100644 --- a/src/client.cc +++ b/src/client.cc @@ -677,7 +677,7 @@ void PClient::FeedMonitors(const std::vector& params) { } } void PClient::SetKey(std::vector& names) { - keys_ = std::move(names); // use std::move clear copy expense + keys_ = std::move(names); // use std::move clear copy expense } } // namespace pikiwidb diff --git a/src/client.h b/src/client.h index e7dc90de4..e2174b717 100644 --- a/src/client.h +++ b/src/client.h @@ -163,7 +163,10 @@ class PClient : public std::enable_shared_from_this, public CmdRes { void SetSubCmdName(const std::string& name); const std::string& SubCmdName() const { return subCmdName_; } std::string FullCmdName() const; // the full name of the command, such as config set|get|rewrite - void SetKey(const std::string& name) { keys_.clear(); keys_.emplace_back(name); } + void SetKey(const std::string& name) { + keys_.clear(); + keys_.emplace_back(name); + } void SetKey(std::vector& names); const std::string& Key() const { return keys_.at(0); } const std::vector& Keys() const { return keys_; } @@ -219,7 +222,6 @@ class PClient : public std::enable_shared_from_this, public CmdRes { std::string cmdName_; // suchAs config std::vector keys_; - // All parameters of this command (including the command itself) // e.g:["set","key","value"] std::vector params_; diff --git a/src/cmd_admin.h b/src/cmd_admin.h index cd1ace0ab..9da3627a8 100644 --- a/src/cmd_admin.h +++ b/src/cmd_admin.h @@ -21,7 +21,7 @@ class CmdConfig : public BaseCmdGroup { bool DoInitial(PClient* client) override { return true; }; private: -// std::vector subCmd_; + // std::vector subCmd_; void DoCmd(PClient* client) override{}; }; diff --git a/src/cmd_kv.cc b/src/cmd_kv.cc index 35fc0f532..d4b0e0942 100644 --- a/src/cmd_kv.cc +++ b/src/cmd_kv.cc @@ -163,7 +163,7 @@ BitCountCmd::BitCountCmd(const std::string& name, int16_t arity) bool BitCountCmd::DoInitial(PClient* client) { size_t paramSize = client->argv_.size(); - if(paramSize != 2 && paramSize != 4) { + if (paramSize != 2 && paramSize != 4) { client->SetRes(CmdRes::kSyntaxErr, kCmdNameBitCount); return false; } @@ -188,7 +188,7 @@ void BitCountCmd::DoCmd(PClient* client) { if (pstd::String2int(client->argv_[2], &start_offset_) == 0 || pstd::String2int(client->argv_[3], &end_offset_) == 0) { client->SetRes(CmdRes::kInvalidInt); - return ; + return; } auto str = GetDecodedString(value); diff --git a/src/cmd_table_manager.h b/src/cmd_table_manager.h index 7c1c217c3..6b2a8ca4a 100644 --- a/src/cmd_table_manager.h +++ b/src/cmd_table_manager.h @@ -16,7 +16,6 @@ #include "base_cmd.h" - namespace pikiwidb { using CmdTable = std::unordered_map>; @@ -28,7 +27,7 @@ class CmdTableManager { public: void InitCmdTable(); - std::pair GetCommand(const std::string& cmdName, PClient* client); + std::pair GetCommand(const std::string& cmdName, PClient* client); // uint32_t DistributeKey(const std::string& key, uint32_t slot_num); bool CmdExist(const std::string& cmd) const; uint32_t GetCmdId(); diff --git a/src/command.h b/src/command.h index 77e2e081e..d1f9c6605 100644 --- a/src/command.h +++ b/src/command.h @@ -9,8 +9,9 @@ #include #include -#include "delegate.h" + #include "common.h" +#include "delegate.h" #include "pstring.h" namespace pikiwidb { @@ -218,4 +219,3 @@ class PCommandTable { }; } // namespace pikiwidb - diff --git a/src/common.h b/src/common.h index f5f07aec8..572b7831a 100644 --- a/src/common.h +++ b/src/common.h @@ -7,12 +7,13 @@ #pragma once -#include #include #include #include +#include #include #include + #include "pstring.h" #define CRLF "\r\n" diff --git a/src/config.h b/src/config.h index f40be4f0c..bcbcd0655 100644 --- a/src/config.h +++ b/src/config.h @@ -88,4 +88,3 @@ extern PConfig g_config; extern bool LoadPikiwiDBConfig(const char* cfgFile, PConfig& cfg); } // namespace pikiwidb - diff --git a/src/crc64.c b/src/crc64.c index ecdba90e0..9f0f03779 100644 --- a/src/crc64.c +++ b/src/crc64.c @@ -40,152 +40,109 @@ #include static const uint64_t crc64_tab[256] = { - UINT64_C(0x0000000000000000), UINT64_C(0x7ad870c830358979), - UINT64_C(0xf5b0e190606b12f2), UINT64_C(0x8f689158505e9b8b), - UINT64_C(0xc038e5739841b68f), UINT64_C(0xbae095bba8743ff6), - UINT64_C(0x358804e3f82aa47d), UINT64_C(0x4f50742bc81f2d04), - UINT64_C(0xab28ecb46814fe75), UINT64_C(0xd1f09c7c5821770c), - UINT64_C(0x5e980d24087fec87), UINT64_C(0x24407dec384a65fe), - UINT64_C(0x6b1009c7f05548fa), UINT64_C(0x11c8790fc060c183), - UINT64_C(0x9ea0e857903e5a08), UINT64_C(0xe478989fa00bd371), - UINT64_C(0x7d08ff3b88be6f81), UINT64_C(0x07d08ff3b88be6f8), - UINT64_C(0x88b81eabe8d57d73), UINT64_C(0xf2606e63d8e0f40a), - UINT64_C(0xbd301a4810ffd90e), UINT64_C(0xc7e86a8020ca5077), - UINT64_C(0x4880fbd87094cbfc), UINT64_C(0x32588b1040a14285), - UINT64_C(0xd620138fe0aa91f4), UINT64_C(0xacf86347d09f188d), - UINT64_C(0x2390f21f80c18306), UINT64_C(0x594882d7b0f40a7f), - UINT64_C(0x1618f6fc78eb277b), UINT64_C(0x6cc0863448deae02), - UINT64_C(0xe3a8176c18803589), UINT64_C(0x997067a428b5bcf0), - UINT64_C(0xfa11fe77117cdf02), UINT64_C(0x80c98ebf2149567b), - UINT64_C(0x0fa11fe77117cdf0), UINT64_C(0x75796f2f41224489), - UINT64_C(0x3a291b04893d698d), UINT64_C(0x40f16bccb908e0f4), - UINT64_C(0xcf99fa94e9567b7f), UINT64_C(0xb5418a5cd963f206), - UINT64_C(0x513912c379682177), UINT64_C(0x2be1620b495da80e), - UINT64_C(0xa489f35319033385), UINT64_C(0xde51839b2936bafc), - UINT64_C(0x9101f7b0e12997f8), UINT64_C(0xebd98778d11c1e81), - UINT64_C(0x64b116208142850a), UINT64_C(0x1e6966e8b1770c73), - UINT64_C(0x8719014c99c2b083), UINT64_C(0xfdc17184a9f739fa), - UINT64_C(0x72a9e0dcf9a9a271), UINT64_C(0x08719014c99c2b08), - UINT64_C(0x4721e43f0183060c), UINT64_C(0x3df994f731b68f75), - UINT64_C(0xb29105af61e814fe), UINT64_C(0xc849756751dd9d87), - UINT64_C(0x2c31edf8f1d64ef6), UINT64_C(0x56e99d30c1e3c78f), - UINT64_C(0xd9810c6891bd5c04), UINT64_C(0xa3597ca0a188d57d), - UINT64_C(0xec09088b6997f879), UINT64_C(0x96d1784359a27100), - UINT64_C(0x19b9e91b09fcea8b), UINT64_C(0x636199d339c963f2), - UINT64_C(0xdf7adabd7a6e2d6f), UINT64_C(0xa5a2aa754a5ba416), - UINT64_C(0x2aca3b2d1a053f9d), UINT64_C(0x50124be52a30b6e4), - UINT64_C(0x1f423fcee22f9be0), UINT64_C(0x659a4f06d21a1299), - UINT64_C(0xeaf2de5e82448912), UINT64_C(0x902aae96b271006b), - UINT64_C(0x74523609127ad31a), UINT64_C(0x0e8a46c1224f5a63), - UINT64_C(0x81e2d7997211c1e8), UINT64_C(0xfb3aa75142244891), - UINT64_C(0xb46ad37a8a3b6595), UINT64_C(0xceb2a3b2ba0eecec), - UINT64_C(0x41da32eaea507767), UINT64_C(0x3b024222da65fe1e), - UINT64_C(0xa2722586f2d042ee), UINT64_C(0xd8aa554ec2e5cb97), - UINT64_C(0x57c2c41692bb501c), UINT64_C(0x2d1ab4dea28ed965), - UINT64_C(0x624ac0f56a91f461), UINT64_C(0x1892b03d5aa47d18), - UINT64_C(0x97fa21650afae693), UINT64_C(0xed2251ad3acf6fea), - UINT64_C(0x095ac9329ac4bc9b), UINT64_C(0x7382b9faaaf135e2), - UINT64_C(0xfcea28a2faafae69), UINT64_C(0x8632586aca9a2710), - UINT64_C(0xc9622c4102850a14), UINT64_C(0xb3ba5c8932b0836d), - UINT64_C(0x3cd2cdd162ee18e6), UINT64_C(0x460abd1952db919f), - UINT64_C(0x256b24ca6b12f26d), UINT64_C(0x5fb354025b277b14), - UINT64_C(0xd0dbc55a0b79e09f), UINT64_C(0xaa03b5923b4c69e6), - UINT64_C(0xe553c1b9f35344e2), UINT64_C(0x9f8bb171c366cd9b), - UINT64_C(0x10e3202993385610), UINT64_C(0x6a3b50e1a30ddf69), - UINT64_C(0x8e43c87e03060c18), UINT64_C(0xf49bb8b633338561), - UINT64_C(0x7bf329ee636d1eea), UINT64_C(0x012b592653589793), - UINT64_C(0x4e7b2d0d9b47ba97), UINT64_C(0x34a35dc5ab7233ee), - UINT64_C(0xbbcbcc9dfb2ca865), UINT64_C(0xc113bc55cb19211c), - UINT64_C(0x5863dbf1e3ac9dec), UINT64_C(0x22bbab39d3991495), - UINT64_C(0xadd33a6183c78f1e), UINT64_C(0xd70b4aa9b3f20667), - UINT64_C(0x985b3e827bed2b63), UINT64_C(0xe2834e4a4bd8a21a), - UINT64_C(0x6debdf121b863991), UINT64_C(0x1733afda2bb3b0e8), - UINT64_C(0xf34b37458bb86399), UINT64_C(0x8993478dbb8deae0), - UINT64_C(0x06fbd6d5ebd3716b), UINT64_C(0x7c23a61ddbe6f812), - UINT64_C(0x3373d23613f9d516), UINT64_C(0x49aba2fe23cc5c6f), - UINT64_C(0xc6c333a67392c7e4), UINT64_C(0xbc1b436e43a74e9d), - UINT64_C(0x95ac9329ac4bc9b5), UINT64_C(0xef74e3e19c7e40cc), - UINT64_C(0x601c72b9cc20db47), UINT64_C(0x1ac40271fc15523e), - UINT64_C(0x5594765a340a7f3a), UINT64_C(0x2f4c0692043ff643), - UINT64_C(0xa02497ca54616dc8), UINT64_C(0xdafce7026454e4b1), - UINT64_C(0x3e847f9dc45f37c0), UINT64_C(0x445c0f55f46abeb9), - UINT64_C(0xcb349e0da4342532), UINT64_C(0xb1eceec59401ac4b), - UINT64_C(0xfebc9aee5c1e814f), UINT64_C(0x8464ea266c2b0836), - UINT64_C(0x0b0c7b7e3c7593bd), UINT64_C(0x71d40bb60c401ac4), - UINT64_C(0xe8a46c1224f5a634), UINT64_C(0x927c1cda14c02f4d), - UINT64_C(0x1d148d82449eb4c6), UINT64_C(0x67ccfd4a74ab3dbf), - UINT64_C(0x289c8961bcb410bb), UINT64_C(0x5244f9a98c8199c2), - UINT64_C(0xdd2c68f1dcdf0249), UINT64_C(0xa7f41839ecea8b30), - UINT64_C(0x438c80a64ce15841), UINT64_C(0x3954f06e7cd4d138), - UINT64_C(0xb63c61362c8a4ab3), UINT64_C(0xcce411fe1cbfc3ca), - UINT64_C(0x83b465d5d4a0eece), UINT64_C(0xf96c151de49567b7), - UINT64_C(0x76048445b4cbfc3c), UINT64_C(0x0cdcf48d84fe7545), - UINT64_C(0x6fbd6d5ebd3716b7), UINT64_C(0x15651d968d029fce), - UINT64_C(0x9a0d8ccedd5c0445), UINT64_C(0xe0d5fc06ed698d3c), - UINT64_C(0xaf85882d2576a038), UINT64_C(0xd55df8e515432941), - UINT64_C(0x5a3569bd451db2ca), UINT64_C(0x20ed197575283bb3), - UINT64_C(0xc49581ead523e8c2), UINT64_C(0xbe4df122e51661bb), - UINT64_C(0x3125607ab548fa30), UINT64_C(0x4bfd10b2857d7349), - UINT64_C(0x04ad64994d625e4d), UINT64_C(0x7e7514517d57d734), - UINT64_C(0xf11d85092d094cbf), UINT64_C(0x8bc5f5c11d3cc5c6), - UINT64_C(0x12b5926535897936), UINT64_C(0x686de2ad05bcf04f), - UINT64_C(0xe70573f555e26bc4), UINT64_C(0x9ddd033d65d7e2bd), - UINT64_C(0xd28d7716adc8cfb9), UINT64_C(0xa85507de9dfd46c0), - UINT64_C(0x273d9686cda3dd4b), UINT64_C(0x5de5e64efd965432), - UINT64_C(0xb99d7ed15d9d8743), UINT64_C(0xc3450e196da80e3a), - UINT64_C(0x4c2d9f413df695b1), UINT64_C(0x36f5ef890dc31cc8), - UINT64_C(0x79a59ba2c5dc31cc), UINT64_C(0x037deb6af5e9b8b5), - UINT64_C(0x8c157a32a5b7233e), UINT64_C(0xf6cd0afa9582aa47), - UINT64_C(0x4ad64994d625e4da), UINT64_C(0x300e395ce6106da3), - UINT64_C(0xbf66a804b64ef628), UINT64_C(0xc5bed8cc867b7f51), - UINT64_C(0x8aeeace74e645255), UINT64_C(0xf036dc2f7e51db2c), - UINT64_C(0x7f5e4d772e0f40a7), UINT64_C(0x05863dbf1e3ac9de), - UINT64_C(0xe1fea520be311aaf), UINT64_C(0x9b26d5e88e0493d6), - UINT64_C(0x144e44b0de5a085d), UINT64_C(0x6e963478ee6f8124), - UINT64_C(0x21c640532670ac20), UINT64_C(0x5b1e309b16452559), - UINT64_C(0xd476a1c3461bbed2), UINT64_C(0xaeaed10b762e37ab), - UINT64_C(0x37deb6af5e9b8b5b), UINT64_C(0x4d06c6676eae0222), - UINT64_C(0xc26e573f3ef099a9), UINT64_C(0xb8b627f70ec510d0), - UINT64_C(0xf7e653dcc6da3dd4), UINT64_C(0x8d3e2314f6efb4ad), - UINT64_C(0x0256b24ca6b12f26), UINT64_C(0x788ec2849684a65f), - UINT64_C(0x9cf65a1b368f752e), UINT64_C(0xe62e2ad306bafc57), - UINT64_C(0x6946bb8b56e467dc), UINT64_C(0x139ecb4366d1eea5), - UINT64_C(0x5ccebf68aecec3a1), UINT64_C(0x2616cfa09efb4ad8), - UINT64_C(0xa97e5ef8cea5d153), UINT64_C(0xd3a62e30fe90582a), - UINT64_C(0xb0c7b7e3c7593bd8), UINT64_C(0xca1fc72bf76cb2a1), - UINT64_C(0x45775673a732292a), UINT64_C(0x3faf26bb9707a053), - UINT64_C(0x70ff52905f188d57), UINT64_C(0x0a2722586f2d042e), - UINT64_C(0x854fb3003f739fa5), UINT64_C(0xff97c3c80f4616dc), - UINT64_C(0x1bef5b57af4dc5ad), UINT64_C(0x61372b9f9f784cd4), - UINT64_C(0xee5fbac7cf26d75f), UINT64_C(0x9487ca0fff135e26), - UINT64_C(0xdbd7be24370c7322), UINT64_C(0xa10fceec0739fa5b), - UINT64_C(0x2e675fb4576761d0), UINT64_C(0x54bf2f7c6752e8a9), - UINT64_C(0xcdcf48d84fe75459), UINT64_C(0xb71738107fd2dd20), - UINT64_C(0x387fa9482f8c46ab), UINT64_C(0x42a7d9801fb9cfd2), - UINT64_C(0x0df7adabd7a6e2d6), UINT64_C(0x772fdd63e7936baf), - UINT64_C(0xf8474c3bb7cdf024), UINT64_C(0x829f3cf387f8795d), - UINT64_C(0x66e7a46c27f3aa2c), UINT64_C(0x1c3fd4a417c62355), - UINT64_C(0x935745fc4798b8de), UINT64_C(0xe98f353477ad31a7), - UINT64_C(0xa6df411fbfb21ca3), UINT64_C(0xdc0731d78f8795da), - UINT64_C(0x536fa08fdfd90e51), UINT64_C(0x29b7d047efec8728), + UINT64_C(0x0000000000000000), UINT64_C(0x7ad870c830358979), UINT64_C(0xf5b0e190606b12f2), + UINT64_C(0x8f689158505e9b8b), UINT64_C(0xc038e5739841b68f), UINT64_C(0xbae095bba8743ff6), + UINT64_C(0x358804e3f82aa47d), UINT64_C(0x4f50742bc81f2d04), UINT64_C(0xab28ecb46814fe75), + UINT64_C(0xd1f09c7c5821770c), UINT64_C(0x5e980d24087fec87), UINT64_C(0x24407dec384a65fe), + UINT64_C(0x6b1009c7f05548fa), UINT64_C(0x11c8790fc060c183), UINT64_C(0x9ea0e857903e5a08), + UINT64_C(0xe478989fa00bd371), UINT64_C(0x7d08ff3b88be6f81), UINT64_C(0x07d08ff3b88be6f8), + UINT64_C(0x88b81eabe8d57d73), UINT64_C(0xf2606e63d8e0f40a), UINT64_C(0xbd301a4810ffd90e), + UINT64_C(0xc7e86a8020ca5077), UINT64_C(0x4880fbd87094cbfc), UINT64_C(0x32588b1040a14285), + UINT64_C(0xd620138fe0aa91f4), UINT64_C(0xacf86347d09f188d), UINT64_C(0x2390f21f80c18306), + UINT64_C(0x594882d7b0f40a7f), UINT64_C(0x1618f6fc78eb277b), UINT64_C(0x6cc0863448deae02), + UINT64_C(0xe3a8176c18803589), UINT64_C(0x997067a428b5bcf0), UINT64_C(0xfa11fe77117cdf02), + UINT64_C(0x80c98ebf2149567b), UINT64_C(0x0fa11fe77117cdf0), UINT64_C(0x75796f2f41224489), + UINT64_C(0x3a291b04893d698d), UINT64_C(0x40f16bccb908e0f4), UINT64_C(0xcf99fa94e9567b7f), + UINT64_C(0xb5418a5cd963f206), UINT64_C(0x513912c379682177), UINT64_C(0x2be1620b495da80e), + UINT64_C(0xa489f35319033385), UINT64_C(0xde51839b2936bafc), UINT64_C(0x9101f7b0e12997f8), + UINT64_C(0xebd98778d11c1e81), UINT64_C(0x64b116208142850a), UINT64_C(0x1e6966e8b1770c73), + UINT64_C(0x8719014c99c2b083), UINT64_C(0xfdc17184a9f739fa), UINT64_C(0x72a9e0dcf9a9a271), + UINT64_C(0x08719014c99c2b08), UINT64_C(0x4721e43f0183060c), UINT64_C(0x3df994f731b68f75), + UINT64_C(0xb29105af61e814fe), UINT64_C(0xc849756751dd9d87), UINT64_C(0x2c31edf8f1d64ef6), + UINT64_C(0x56e99d30c1e3c78f), UINT64_C(0xd9810c6891bd5c04), UINT64_C(0xa3597ca0a188d57d), + UINT64_C(0xec09088b6997f879), UINT64_C(0x96d1784359a27100), UINT64_C(0x19b9e91b09fcea8b), + UINT64_C(0x636199d339c963f2), UINT64_C(0xdf7adabd7a6e2d6f), UINT64_C(0xa5a2aa754a5ba416), + UINT64_C(0x2aca3b2d1a053f9d), UINT64_C(0x50124be52a30b6e4), UINT64_C(0x1f423fcee22f9be0), + UINT64_C(0x659a4f06d21a1299), UINT64_C(0xeaf2de5e82448912), UINT64_C(0x902aae96b271006b), + UINT64_C(0x74523609127ad31a), UINT64_C(0x0e8a46c1224f5a63), UINT64_C(0x81e2d7997211c1e8), + UINT64_C(0xfb3aa75142244891), UINT64_C(0xb46ad37a8a3b6595), UINT64_C(0xceb2a3b2ba0eecec), + UINT64_C(0x41da32eaea507767), UINT64_C(0x3b024222da65fe1e), UINT64_C(0xa2722586f2d042ee), + UINT64_C(0xd8aa554ec2e5cb97), UINT64_C(0x57c2c41692bb501c), UINT64_C(0x2d1ab4dea28ed965), + UINT64_C(0x624ac0f56a91f461), UINT64_C(0x1892b03d5aa47d18), UINT64_C(0x97fa21650afae693), + UINT64_C(0xed2251ad3acf6fea), UINT64_C(0x095ac9329ac4bc9b), UINT64_C(0x7382b9faaaf135e2), + UINT64_C(0xfcea28a2faafae69), UINT64_C(0x8632586aca9a2710), UINT64_C(0xc9622c4102850a14), + UINT64_C(0xb3ba5c8932b0836d), UINT64_C(0x3cd2cdd162ee18e6), UINT64_C(0x460abd1952db919f), + UINT64_C(0x256b24ca6b12f26d), UINT64_C(0x5fb354025b277b14), UINT64_C(0xd0dbc55a0b79e09f), + UINT64_C(0xaa03b5923b4c69e6), UINT64_C(0xe553c1b9f35344e2), UINT64_C(0x9f8bb171c366cd9b), + UINT64_C(0x10e3202993385610), UINT64_C(0x6a3b50e1a30ddf69), UINT64_C(0x8e43c87e03060c18), + UINT64_C(0xf49bb8b633338561), UINT64_C(0x7bf329ee636d1eea), UINT64_C(0x012b592653589793), + UINT64_C(0x4e7b2d0d9b47ba97), UINT64_C(0x34a35dc5ab7233ee), UINT64_C(0xbbcbcc9dfb2ca865), + UINT64_C(0xc113bc55cb19211c), UINT64_C(0x5863dbf1e3ac9dec), UINT64_C(0x22bbab39d3991495), + UINT64_C(0xadd33a6183c78f1e), UINT64_C(0xd70b4aa9b3f20667), UINT64_C(0x985b3e827bed2b63), + UINT64_C(0xe2834e4a4bd8a21a), UINT64_C(0x6debdf121b863991), UINT64_C(0x1733afda2bb3b0e8), + UINT64_C(0xf34b37458bb86399), UINT64_C(0x8993478dbb8deae0), UINT64_C(0x06fbd6d5ebd3716b), + UINT64_C(0x7c23a61ddbe6f812), UINT64_C(0x3373d23613f9d516), UINT64_C(0x49aba2fe23cc5c6f), + UINT64_C(0xc6c333a67392c7e4), UINT64_C(0xbc1b436e43a74e9d), UINT64_C(0x95ac9329ac4bc9b5), + UINT64_C(0xef74e3e19c7e40cc), UINT64_C(0x601c72b9cc20db47), UINT64_C(0x1ac40271fc15523e), + UINT64_C(0x5594765a340a7f3a), UINT64_C(0x2f4c0692043ff643), UINT64_C(0xa02497ca54616dc8), + UINT64_C(0xdafce7026454e4b1), UINT64_C(0x3e847f9dc45f37c0), UINT64_C(0x445c0f55f46abeb9), + UINT64_C(0xcb349e0da4342532), UINT64_C(0xb1eceec59401ac4b), UINT64_C(0xfebc9aee5c1e814f), + UINT64_C(0x8464ea266c2b0836), UINT64_C(0x0b0c7b7e3c7593bd), UINT64_C(0x71d40bb60c401ac4), + UINT64_C(0xe8a46c1224f5a634), UINT64_C(0x927c1cda14c02f4d), UINT64_C(0x1d148d82449eb4c6), + UINT64_C(0x67ccfd4a74ab3dbf), UINT64_C(0x289c8961bcb410bb), UINT64_C(0x5244f9a98c8199c2), + UINT64_C(0xdd2c68f1dcdf0249), UINT64_C(0xa7f41839ecea8b30), UINT64_C(0x438c80a64ce15841), + UINT64_C(0x3954f06e7cd4d138), UINT64_C(0xb63c61362c8a4ab3), UINT64_C(0xcce411fe1cbfc3ca), + UINT64_C(0x83b465d5d4a0eece), UINT64_C(0xf96c151de49567b7), UINT64_C(0x76048445b4cbfc3c), + UINT64_C(0x0cdcf48d84fe7545), UINT64_C(0x6fbd6d5ebd3716b7), UINT64_C(0x15651d968d029fce), + UINT64_C(0x9a0d8ccedd5c0445), UINT64_C(0xe0d5fc06ed698d3c), UINT64_C(0xaf85882d2576a038), + UINT64_C(0xd55df8e515432941), UINT64_C(0x5a3569bd451db2ca), UINT64_C(0x20ed197575283bb3), + UINT64_C(0xc49581ead523e8c2), UINT64_C(0xbe4df122e51661bb), UINT64_C(0x3125607ab548fa30), + UINT64_C(0x4bfd10b2857d7349), UINT64_C(0x04ad64994d625e4d), UINT64_C(0x7e7514517d57d734), + UINT64_C(0xf11d85092d094cbf), UINT64_C(0x8bc5f5c11d3cc5c6), UINT64_C(0x12b5926535897936), + UINT64_C(0x686de2ad05bcf04f), UINT64_C(0xe70573f555e26bc4), UINT64_C(0x9ddd033d65d7e2bd), + UINT64_C(0xd28d7716adc8cfb9), UINT64_C(0xa85507de9dfd46c0), UINT64_C(0x273d9686cda3dd4b), + UINT64_C(0x5de5e64efd965432), UINT64_C(0xb99d7ed15d9d8743), UINT64_C(0xc3450e196da80e3a), + UINT64_C(0x4c2d9f413df695b1), UINT64_C(0x36f5ef890dc31cc8), UINT64_C(0x79a59ba2c5dc31cc), + UINT64_C(0x037deb6af5e9b8b5), UINT64_C(0x8c157a32a5b7233e), UINT64_C(0xf6cd0afa9582aa47), + UINT64_C(0x4ad64994d625e4da), UINT64_C(0x300e395ce6106da3), UINT64_C(0xbf66a804b64ef628), + UINT64_C(0xc5bed8cc867b7f51), UINT64_C(0x8aeeace74e645255), UINT64_C(0xf036dc2f7e51db2c), + UINT64_C(0x7f5e4d772e0f40a7), UINT64_C(0x05863dbf1e3ac9de), UINT64_C(0xe1fea520be311aaf), + UINT64_C(0x9b26d5e88e0493d6), UINT64_C(0x144e44b0de5a085d), UINT64_C(0x6e963478ee6f8124), + UINT64_C(0x21c640532670ac20), UINT64_C(0x5b1e309b16452559), UINT64_C(0xd476a1c3461bbed2), + UINT64_C(0xaeaed10b762e37ab), UINT64_C(0x37deb6af5e9b8b5b), UINT64_C(0x4d06c6676eae0222), + UINT64_C(0xc26e573f3ef099a9), UINT64_C(0xb8b627f70ec510d0), UINT64_C(0xf7e653dcc6da3dd4), + UINT64_C(0x8d3e2314f6efb4ad), UINT64_C(0x0256b24ca6b12f26), UINT64_C(0x788ec2849684a65f), + UINT64_C(0x9cf65a1b368f752e), UINT64_C(0xe62e2ad306bafc57), UINT64_C(0x6946bb8b56e467dc), + UINT64_C(0x139ecb4366d1eea5), UINT64_C(0x5ccebf68aecec3a1), UINT64_C(0x2616cfa09efb4ad8), + UINT64_C(0xa97e5ef8cea5d153), UINT64_C(0xd3a62e30fe90582a), UINT64_C(0xb0c7b7e3c7593bd8), + UINT64_C(0xca1fc72bf76cb2a1), UINT64_C(0x45775673a732292a), UINT64_C(0x3faf26bb9707a053), + UINT64_C(0x70ff52905f188d57), UINT64_C(0x0a2722586f2d042e), UINT64_C(0x854fb3003f739fa5), + UINT64_C(0xff97c3c80f4616dc), UINT64_C(0x1bef5b57af4dc5ad), UINT64_C(0x61372b9f9f784cd4), + UINT64_C(0xee5fbac7cf26d75f), UINT64_C(0x9487ca0fff135e26), UINT64_C(0xdbd7be24370c7322), + UINT64_C(0xa10fceec0739fa5b), UINT64_C(0x2e675fb4576761d0), UINT64_C(0x54bf2f7c6752e8a9), + UINT64_C(0xcdcf48d84fe75459), UINT64_C(0xb71738107fd2dd20), UINT64_C(0x387fa9482f8c46ab), + UINT64_C(0x42a7d9801fb9cfd2), UINT64_C(0x0df7adabd7a6e2d6), UINT64_C(0x772fdd63e7936baf), + UINT64_C(0xf8474c3bb7cdf024), UINT64_C(0x829f3cf387f8795d), UINT64_C(0x66e7a46c27f3aa2c), + UINT64_C(0x1c3fd4a417c62355), UINT64_C(0x935745fc4798b8de), UINT64_C(0xe98f353477ad31a7), + UINT64_C(0xa6df411fbfb21ca3), UINT64_C(0xdc0731d78f8795da), UINT64_C(0x536fa08fdfd90e51), + UINT64_C(0x29b7d047efec8728), }; uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l) { - uint64_t j; + uint64_t j; - for (j = 0; j < l; j++) { - uint8_t byte = s[j]; - crc = crc64_tab[(uint8_t)crc ^ byte] ^ (crc >> 8); - } - return crc; + for (j = 0; j < l; j++) { + uint8_t byte = s[j]; + crc = crc64_tab[(uint8_t)crc ^ byte] ^ (crc >> 8); + } + return crc; } /* Test main */ #ifdef TEST_MAIN -#include +# include int main(void) { - printf("e9c6d914c4b8d9ca == %016llx\n", - (unsigned long long) crc64(0,(unsigned char*)"123456789",9)); - return 0; + printf("e9c6d914c4b8d9ca == %016llx\n", (unsigned long long)crc64(0, (unsigned char *)"123456789", 9)); + return 0; } #endif diff --git a/src/db.cc b/src/db.cc index 8ef38a97d..344971780 100644 --- a/src/db.cc +++ b/src/db.cc @@ -5,7 +5,6 @@ * of patent rights can be found in the PATENTS file in the same directory. */ - #include "db.h" #include #include @@ -424,7 +423,7 @@ int PDBLoader::Load(const char* filename) { case kTypeQuickList: { PString key = LoadKey(); PObject obj = LoadObject(indicator); -// DEBUG("encounter key = {}, obj.encoding = {}", key, obj.encoding); + // DEBUG("encounter key = {}, obj.encoding = {}", key, obj.encoding); assert(absTimeout >= 0); diff --git a/src/db.h b/src/db.h index 99cf78c7d..78fdf5809 100644 --- a/src/db.h +++ b/src/db.h @@ -70,4 +70,3 @@ class PDBLoader { }; } // namespace pikiwidb - diff --git a/src/dump_interface.h b/src/dump_interface.h index 520e61988..38c34f72d 100644 --- a/src/dump_interface.h +++ b/src/dump_interface.h @@ -30,4 +30,3 @@ class PDumpInterface { }; } // namespace pikiwidb - diff --git a/src/hash.h b/src/hash.h index 171bb11e3..d2a1a5a02 100644 --- a/src/hash.h +++ b/src/hash.h @@ -19,4 +19,3 @@ using PHash = std::unordered_map& res); } // namespace pikiwidb - diff --git a/src/helper.cc b/src/helper.cc index 7bfe99d7e..c96890d5d 100644 --- a/src/helper.cc +++ b/src/helper.cc @@ -149,7 +149,7 @@ void getRandomHexChars(char* p, unsigned int len) { * time() at startup. */ for (j = 0; j < len; j++) { p[j] ^= rand(); - } + } } /* Turn it into hex digits taking just 4 bits out of 8 for every byte. */ for (j = 0; j < len; j++) { @@ -261,19 +261,19 @@ size_t getMemoryInfo(MemoryInfoType type) { while (!found && std::getline(ifs, line)) { switch (type) { case VmPeak: - if (line.find("VmPeak") == 0) { + if (line.find("VmPeak") == 0) { found = true; } break; case VmSize: - if (line.find("VmSize") == 0) { + if (line.find("VmSize") == 0) { found = true; } break; case VmLck: - if (line.find("VmLck") == 0) { + if (line.find("VmLck") == 0) { found = true; } break; @@ -285,13 +285,13 @@ size_t getMemoryInfo(MemoryInfoType type) { break; case VmRSS: - if (line.find("VmRSS") == 0) { + if (line.find("VmRSS") == 0) { found = true; } break; case VmSwap: - if (line.find("VmSwap") == 0) { + if (line.find("VmSwap") == 0) { found = true; } break; diff --git a/src/helper.h b/src/helper.h index bbb845671..db1e89252 100644 --- a/src/helper.h +++ b/src/helper.h @@ -70,8 +70,7 @@ inline typename HASH::const_iterator FollyRandomHashMember(const HASH& container } template -inline size_t FollyScanHashMember(const HASH& container, size_t cursor, size_t count, - std::vector& res) { +inline size_t FollyScanHashMember(const HASH& container, size_t cursor, size_t count, std::vector& res) { if (cursor >= container.size()) { return 0; } @@ -166,4 +165,3 @@ extern std::vector getMemoryInfo(); extern size_t getMemoryInfo(MemoryInfoType type); } // namespace pikiwidb - diff --git a/src/io_thread_pool.cc b/src/io_thread_pool.cc index 017a0bfac..5aec18c93 100644 --- a/src/io_thread_pool.cc +++ b/src/io_thread_pool.cc @@ -65,7 +65,7 @@ void IOThreadPool::Run(int ac, char* av[]) { for (auto& w : worker_threads_) { w.join(); } - + worker_threads_.clear(); INFO("Process stopped, goodbye..."); diff --git a/src/io_thread_pool.h b/src/io_thread_pool.h index 717ce9253..84b51bea3 100644 --- a/src/io_thread_pool.h +++ b/src/io_thread_pool.h @@ -21,7 +21,7 @@ namespace pikiwidb { class IOThreadPool { public: IOThreadPool() = default; - ~IOThreadPool()= default; + ~IOThreadPool() = default; static const size_t GetMaxWorkerNum() { return kMaxWorkers; } diff --git a/src/key_command.cc b/src/key_command.cc index d4abb427f..2aa2f8037 100644 --- a/src/key_command.cc +++ b/src/key_command.cc @@ -5,8 +5,9 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#include #include +#include + #include "log.h" #include "store.h" diff --git a/src/leveldb.cc b/src/leveldb.cc index c5ecc1e0f..ba89e4eb1 100644 --- a/src/leveldb.cc +++ b/src/leveldb.cc @@ -5,7 +5,6 @@ * of patent rights can be found in the PATENTS file in the same directory. */ - #include "leveldb.h" #include "leveldb/db.h" #include "log.h" diff --git a/src/leveldb.h b/src/leveldb.h index f5c493765..2dda9f2d7 100644 --- a/src/leveldb.h +++ b/src/leveldb.h @@ -57,4 +57,3 @@ class PLeveldb : public PDumpInterface { }; } // namespace pikiwidb - diff --git a/src/list.cc b/src/list.cc index 0917772e3..d08d89e30 100644 --- a/src/list.cc +++ b/src/list.cc @@ -52,7 +52,7 @@ static PError push(const vector& params, UnboundedBuffer* reply, ListPo FormatInt(static_cast(list->size()), reply); if (mayReady && !list->empty()) { - if (reply) { + if (reply) { // push must before pop(serve)... Propagate(params); // the push PSTORE.ServeClient(params[1], list); // the pop @@ -134,7 +134,7 @@ PError rpop(const vector& params, UnboundedBuffer* reply) { } static bool blockClient(PClient* client, const PString& key, uint64_t timeout, ListPosition pos, - const PString* dstList = 0) { + const PString* dstList = 0) { auto now = ::Now(); if (timeout > 0) { @@ -147,8 +147,8 @@ static bool blockClient(PClient* client, const PString& key, uint64_t timeout, L } static PError genericBlockedPop(vector::const_iterator keyBegin, vector::const_iterator keyEnd, - UnboundedBuffer* reply, ListPosition pos, long timeout, - const PString* target = nullptr, bool withKey = true) { + UnboundedBuffer* reply, ListPosition pos, long timeout, const PString* target = nullptr, + bool withKey = true) { for (auto it(keyBegin); it != keyEnd; ++it) { PString result; PError err = GenericPop(*it, pos, result); @@ -365,7 +365,7 @@ static void Index2Iterator(long start, long end, PList& list, PList::iterator* b static size_t GetRange(long start, long end, PList& list, PList::iterator* beginIt = nullptr, PList::iterator* endIt = nullptr) { size_t rangeLen = 0; - if (start > end) { // empty + if (start > end) { // empty if (beginIt) { *beginIt = list.end(); } diff --git a/src/list.h b/src/list.h index 5af8d31aa..01dd0ed4f 100644 --- a/src/list.h +++ b/src/list.h @@ -19,4 +19,3 @@ enum class ListPosition { using PList = std::list; } // namespace pikiwidb - diff --git a/src/multi.h b/src/multi.h index c7683b92a..79e29a5cc 100644 --- a/src/multi.h +++ b/src/multi.h @@ -40,4 +40,3 @@ class PMulti { }; } // namespace pikiwidb - diff --git a/src/net/config_parser.h b/src/net/config_parser.h index a5846d063..2b4373cff 100644 --- a/src/net/config_parser.h +++ b/src/net/config_parser.h @@ -13,7 +13,7 @@ #include #ifdef CONFIG_DEBUG -#include +# include #endif class ConfigParser { diff --git a/src/net/lzf/lzf.h b/src/net/lzf/lzf.h index 5e89000bc..1801c6457 100644 --- a/src/net/lzf/lzf.h +++ b/src/net/lzf/lzf.h @@ -72,9 +72,7 @@ * and lzf_c.c. * */ -unsigned int -lzf_compress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len); +unsigned int lzf_compress(const void *const in_data, unsigned int in_len, void *out_data, unsigned int out_len); /* * Decompress data compressed with some version of the lzf_compress @@ -91,7 +89,4 @@ lzf_compress (const void *const in_data, unsigned int in_len, * * This function is very fast, about as fast as a copying loop. */ -unsigned int -lzf_decompress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len); - +unsigned int lzf_decompress(const void *const in_data, unsigned int in_len, void *out_data, unsigned int out_len); diff --git a/src/net/lzf/lzf_c.c b/src/net/lzf/lzf_c.c index 2367ae056..8263ae328 100644 --- a/src/net/lzf/lzf_c.c +++ b/src/net/lzf/lzf_c.c @@ -1,16 +1,16 @@ /* * Copyright (c) 2000-2008 Marc Alexander Lehmann - * + * * Redistribution and use in source and binary forms, with or without modifica- * tion, 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. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO @@ -45,15 +45,15 @@ * it works ;) */ #ifndef FRST -# define FRST(p) (((p[0]) << 8) | p[1]) -# define NEXT(v,p) (((v) << 8) | p[2]) -# if ULTRA_FAST -# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1)) -# elif VERY_FAST -# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) -# else -# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1)) -# endif +# define FRST(p) (((p[0]) << 8) | p[1]) +# define NEXT(v, p) (((v) << 8) | p[2]) +# if ULTRA_FAST +# define IDX(h) (((h >> (3 * 8 - HLOG)) - h) & (HSIZE - 1)) +# elif VERY_FAST +# define IDX(h) (((h >> (3 * 8 - HLOG)) - h * 5) & (HSIZE - 1)) +# else +# define IDX(h) ((((h ^ (h << 5)) >> (3 * 8 - HLOG)) - h * 5) & (HSIZE - 1)) +# endif #endif /* * IDX works because it is very similar to a multiplicative hash, e.g. @@ -66,25 +66,25 @@ #if 0 /* original lzv-like hash function, much worse and thus slower */ -# define FRST(p) (p[0] << 5) ^ p[1] -# define NEXT(v,p) ((v) << 5) ^ p[2] -# define IDX(h) ((h) & (HSIZE - 1)) +# define FRST(p) (p[0] << 5) ^ p[1] +# define NEXT(v, p) ((v) << 5) ^ p[2] +# define IDX(h) ((h) & (HSIZE - 1)) #endif -#define MAX_LIT (1 << 5) -#define MAX_OFF (1 << 13) -#define MAX_REF ((1 << 8) + (1 << 3)) +#define MAX_LIT (1 << 5) +#define MAX_OFF (1 << 13) +#define MAX_REF ((1 << 8) + (1 << 3)) #if __GNUC__ >= 3 -# define expect(expr,value) __builtin_expect ((expr),(value)) -# define inline inline +# define expect(expr, value) __builtin_expect((expr), (value)) +# define inline inline #else -# define expect(expr,value) (expr) -# define inline static +# define expect(expr, value) (expr) +# define inline static #endif -#define expect_false(expr) expect ((expr) != 0, 0) -#define expect_true(expr) expect ((expr) != 0, 1) +#define expect_false(expr) expect((expr) != 0, 0) +#define expect_true(expr) expect((expr) != 0, 1) /* * compressed format @@ -95,22 +95,20 @@ * */ -unsigned int -lzf_compress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len +unsigned int lzf_compress(const void *const in_data, unsigned int in_len, void *out_data, unsigned int out_len #if LZF_STATE_ARG - , LZF_STATE htab + , + LZF_STATE htab #endif - ) -{ +) { #if !LZF_STATE_ARG LZF_STATE htab; #endif const u8 **hslot; const u8 *ip = (const u8 *)in_data; - u8 *op = (u8 *)out_data; - const u8 *in_end = ip + in_len; - u8 *out_end = op + out_len; + u8 *op = (u8 *)out_data; + const u8 *in_end = ip + in_len; + u8 *out_end = op + out_len; const u8 *ref; /* off requires a type wide enough to hold a general pointer difference. @@ -120,7 +118,7 @@ lzf_compress (const void *const in_data, unsigned int in_len, * and fails to support both assumptions is windows 64 bit, we make a * special workaround for it. */ -#if defined (WIN32) && defined (_M_X64) +#if defined(WIN32) && defined(_M_X64) unsigned _int64 off; /* workaround for missing POSIX compliance */ #else unsigned long off; @@ -128,168 +126,166 @@ lzf_compress (const void *const in_data, unsigned int in_len, unsigned int hval; int lit; - if (!in_len || !out_len) - return 0; + if (!in_len || !out_len) return 0; #if INIT_HTAB - memset (htab, 0, sizeof (htab)); -# if 0 + memset(htab, 0, sizeof(htab)); +# if 0 for (hslot = htab; hslot < htab + HSIZE; hslot++) *hslot++ = ip; -# endif +# endif #endif - lit = 0; op++; /* start run */ + lit = 0; + op++; /* start run */ - hval = FRST (ip); - while (ip < in_end - 2) - { - hval = NEXT (hval, ip); - hslot = htab + IDX (hval); - ref = *hslot; *hslot = ip; + hval = FRST(ip); + while (ip < in_end - 2) { + hval = NEXT(hval, ip); + hslot = htab + IDX(hval); + ref = *hslot; + *hslot = ip; - if (1 + if (1 #if INIT_HTAB - && ref < ip /* the next test will actually take care of this, but this is faster */ + && ref < ip /* the next test will actually take care of this, but this is faster */ #endif - && (off = ip - ref - 1) < MAX_OFF - && ip + 4 < in_end - && ref > (u8 *)in_data + && (off = ip - ref - 1) < MAX_OFF && ip + 4 < in_end && ref > (u8 *)in_data #if STRICT_ALIGN - && ref[0] == ip[0] - && ref[1] == ip[1] - && ref[2] == ip[2] + && ref[0] == ip[0] && ref[1] == ip[1] && ref[2] == ip[2] #else - && *(u16 *)ref == *(u16 *)ip - && ref[2] == ip[2] + && *(u16 *)ref == *(u16 *)ip && ref[2] == ip[2] #endif - ) - { - /* match found at *ref++ */ - unsigned int len = 2; - unsigned int maxlen = (unsigned int)(in_end - ip - len); - maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; - - op [- lit - 1] = lit - 1; /* stop run */ - op -= !lit; /* undo run if length is zero */ - - if (expect_false (op + 3 + 1 >= out_end)) - return 0; - - for (;;) - { - if (expect_true (maxlen > 16)) - { - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - len++; if (ref [len] != ip [len]) break; - } - - do - len++; - while (len < maxlen && ref[len] == ip[len]); - - break; - } - - len -= 2; /* len is now #octets - 1 */ - ip++; - - if (len < 7) - { - *op++ = (off >> 8) + (len << 5); - } - else - { - *op++ = (off >> 8) + ( 7 << 5); - *op++ = len - 7; - } - - *op++ = off; - lit = 0; op++; /* start run */ - - ip += len + 1; - - if (expect_false (ip >= in_end - 2)) - break; + ) { + /* match found at *ref++ */ + unsigned int len = 2; + unsigned int maxlen = (unsigned int)(in_end - ip - len); + maxlen = maxlen > MAX_REF ? MAX_REF : maxlen; + + op[-lit - 1] = lit - 1; /* stop run */ + op -= !lit; /* undo run if length is zero */ + + if (expect_false(op + 3 + 1 >= out_end)) return 0; + + for (;;) { + if (expect_true(maxlen > 16)) { + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + len++; + if (ref[len] != ip[len]) break; + } + + do len++; + while (len < maxlen && ref[len] == ip[len]); + + break; + } + + len -= 2; /* len is now #octets - 1 */ + ip++; + + if (len < 7) { + *op++ = (off >> 8) + (len << 5); + } else { + *op++ = (off >> 8) + (7 << 5); + *op++ = len - 7; + } + + *op++ = off; + lit = 0; + op++; /* start run */ + + ip += len + 1; + + if (expect_false(ip >= in_end - 2)) break; #if ULTRA_FAST || VERY_FAST - --ip; -# if VERY_FAST && !ULTRA_FAST - --ip; -# endif - hval = FRST (ip); - - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip; - ip++; - -# if VERY_FAST && !ULTRA_FAST - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip; - ip++; -# endif + --ip; +# if VERY_FAST && !ULTRA_FAST + --ip; +# endif + hval = FRST(ip); + + hval = NEXT(hval, ip); + htab[IDX(hval)] = ip; + ip++; + +# if VERY_FAST && !ULTRA_FAST + hval = NEXT(hval, ip); + htab[IDX(hval)] = ip; + ip++; +# endif #else - ip -= len + 1; - - do - { - hval = NEXT (hval, ip); - htab[IDX (hval)] = ip; - ip++; - } - while (len--); + ip -= len + 1; + + do { + hval = NEXT(hval, ip); + htab[IDX(hval)] = ip; + ip++; + } while (len--); #endif - } - else - { - /* one more literal byte we must copy */ - if (expect_false (op >= out_end)) - return 0; - - lit++; *op++ = *ip++; - - if (expect_false (lit == MAX_LIT)) - { - op [- lit - 1] = lit - 1; /* stop run */ - lit = 0; op++; /* start run */ - } - } + } else { + /* one more literal byte we must copy */ + if (expect_false(op >= out_end)) return 0; + + lit++; + *op++ = *ip++; + + if (expect_false(lit == MAX_LIT)) { + op[-lit - 1] = lit - 1; /* stop run */ + lit = 0; + op++; /* start run */ + } } + } if (op + 3 > out_end) /* at most 3 bytes can be missing here */ return 0; - while (ip < in_end) - { - lit++; *op++ = *ip++; + while (ip < in_end) { + lit++; + *op++ = *ip++; - if (expect_false (lit == MAX_LIT)) - { - op [- lit - 1] = lit - 1; /* stop run */ - lit = 0; op++; /* start run */ - } + if (expect_false(lit == MAX_LIT)) { + op[-lit - 1] = lit - 1; /* stop run */ + lit = 0; + op++; /* start run */ } + } - op [- lit - 1] = lit - 1; /* end run */ - op -= !lit; /* undo run if length is zero */ + op[-lit - 1] = lit - 1; /* end run */ + op -= !lit; /* undo run if length is zero */ return (unsigned int)(op - (u8 *)out_data); } - diff --git a/src/net/lzf/lzf_d.c b/src/net/lzf/lzf_d.c index 1df45c530..050ea2ccb 100644 --- a/src/net/lzf/lzf_d.c +++ b/src/net/lzf/lzf_d.c @@ -1,16 +1,16 @@ /* * Copyright (c) 2000-2007 Marc Alexander Lehmann - * + * * Redistribution and use in source and binary forms, with or without modifica- * tion, 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. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO @@ -37,10 +37,10 @@ #include "lzfp.h" #if AVOID_ERRNO -# define SET_ERRNO(n) +# define SET_ERRNO(n) #else -# include -# define SET_ERRNO(n) errno = (n) +# include +# define SET_ERRNO(n) errno = (n) #endif /* @@ -52,99 +52,83 @@ #endif */ -unsigned int -lzf_decompress (const void *const in_data, unsigned int in_len, - void *out_data, unsigned int out_len) -{ +unsigned int lzf_decompress(const void *const in_data, unsigned int in_len, void *out_data, unsigned int out_len) { u8 const *ip = (const u8 *)in_data; - u8 *op = (u8 *)out_data; - u8 const *const in_end = ip + in_len; - u8 *const out_end = op + out_len; + u8 *op = (u8 *)out_data; + u8 const *const in_end = ip + in_len; + u8 *const out_end = op + out_len; - do - { - unsigned int ctrl = *ip++; + do { + unsigned int ctrl = *ip++; - if (ctrl < (1 << 5)) /* literal run */ - { - ctrl++; + if (ctrl < (1 << 5)) /* literal run */ + { + ctrl++; - if (op + ctrl > out_end) - { - SET_ERRNO (E2BIG); - return 0; - } + if (op + ctrl > out_end) { + SET_ERRNO(E2BIG); + return 0; + } #if CHECK_INPUT - if (ip + ctrl > in_end) - { - SET_ERRNO (EINVAL); - return 0; - } + if (ip + ctrl > in_end) { + SET_ERRNO(EINVAL); + return 0; + } #endif #ifdef lzf_movsb - lzf_movsb (op, ip, ctrl); + lzf_movsb(op, ip, ctrl); #else - do - *op++ = *ip++; - while (--ctrl); + do *op++ = *ip++; + while (--ctrl); #endif - } - else /* back reference */ - { - unsigned int len = ctrl >> 5; + } else /* back reference */ + { + unsigned int len = ctrl >> 5; - u8 *ref = op - ((ctrl & 0x1f) << 8) - 1; + u8 *ref = op - ((ctrl & 0x1f) << 8) - 1; #if CHECK_INPUT - if (ip >= in_end) - { - SET_ERRNO (EINVAL); - return 0; - } + if (ip >= in_end) { + SET_ERRNO(EINVAL); + return 0; + } #endif - if (len == 7) - { - len += *ip++; + if (len == 7) { + len += *ip++; #if CHECK_INPUT - if (ip >= in_end) - { - SET_ERRNO (EINVAL); - return 0; - } + if (ip >= in_end) { + SET_ERRNO(EINVAL); + return 0; + } #endif - } + } - ref -= *ip++; + ref -= *ip++; - if (op + len + 2 > out_end) - { - SET_ERRNO (E2BIG); - return 0; - } + if (op + len + 2 > out_end) { + SET_ERRNO(E2BIG); + return 0; + } - if (ref < (u8 *)out_data) - { - SET_ERRNO (EINVAL); - return 0; - } + if (ref < (u8 *)out_data) { + SET_ERRNO(EINVAL); + return 0; + } #ifdef lzf_movsb - len += 2; - lzf_movsb (op, ref, len); + len += 2; + lzf_movsb(op, ref, len); #else - *op++ = *ref++; - *op++ = *ref++; + *op++ = *ref++; + *op++ = *ref++; - do - *op++ = *ref++; - while (--len); + do *op++ = *ref++; + while (--len); #endif - } } - while (ip < in_end); + } while (ip < in_end); return (unsigned int)(op - (u8 *)out_data); } - diff --git a/src/net/lzf/lzfp.h b/src/net/lzf/lzfp.h index 0ca2cdcc1..0ad4ba767 100644 --- a/src/net/lzf/lzfp.h +++ b/src/net/lzf/lzfp.h @@ -39,7 +39,7 @@ #define STANDALONE 1 /* at the moment, this is ok. */ #ifndef STANDALONE -# include "lzf.h" +# include "lzf.h" #endif /* @@ -51,7 +51,7 @@ * For best compression, use 15 or 16 (or more, up to 23). */ #ifndef HLOG -# define HLOG 16 +# define HLOG 16 #endif /* @@ -60,7 +60,7 @@ * (very roughly) 15% faster. This is the preferred mode of operation. */ #ifndef VERY_FAST -# define VERY_FAST 1 +# define VERY_FAST 1 #endif /* @@ -71,14 +71,14 @@ * possibly disable this for text data. */ #ifndef ULTRA_FAST -# define ULTRA_FAST 0 +# define ULTRA_FAST 0 #endif /* * Unconditionally aligning does not cost very much, so do it if unsure */ #ifndef STRICT_ALIGN -# define STRICT_ALIGN !(defined(__i386) || defined (__amd64)) +# define STRICT_ALIGN !(defined(__i386) || defined(__amd64)) #endif /* @@ -87,7 +87,7 @@ * deterministic/repeatable when the configuration otherwise is the same). */ #ifndef INIT_HTAB -# define INIT_HTAB 0 +# define INIT_HTAB 0 #endif /* @@ -96,7 +96,7 @@ * the documentation in lzf.h. */ #ifndef AVOID_ERRNO -# define AVOID_ERRNO 0 +# define AVOID_ERRNO 0 #endif /* @@ -105,7 +105,7 @@ * NOTE: this breaks the prototype in lzf.h. */ #ifndef LZF_STATE_ARG -# define LZF_STATE_ARG 0 +# define LZF_STATE_ARG 0 #endif /* @@ -117,7 +117,7 @@ * (<1% slowdown), but might slow down older cpus considerably. */ #ifndef CHECK_INPUT -# define CHECK_INPUT 1 +# define CHECK_INPUT 1 #endif /*****************************************************************************/ @@ -129,27 +129,27 @@ typedef const u8 *LZF_STATE[1 << (HLOG)]; #if !STRICT_ALIGN /* for unaligned accesses we need a 16 bit datatype. */ -# include -# if USHRT_MAX == 65535 - typedef unsigned short u16; -# elif UINT_MAX == 65535 - typedef unsigned int u16; -# else -# undef STRICT_ALIGN -# define STRICT_ALIGN 1 -# endif +# include +# if USHRT_MAX == 65535 +typedef unsigned short u16; +# elif UINT_MAX == 65535 +typedef unsigned int u16; +# else +# undef STRICT_ALIGN +# define STRICT_ALIGN 1 +# endif #endif #if ULTRA_FAST -# if defined(VERY_FAST) -# undef VERY_FAST -# endif +# if defined(VERY_FAST) +# undef VERY_FAST +# endif #endif #if INIT_HTAB -# ifdef __cplusplus -# include -# else -# include -# endif +# ifdef __cplusplus +# include +# else +# include +# endif #endif diff --git a/src/net/tcp_connection.h b/src/net/tcp_connection.h index 923a3710a..7d94ae92a 100644 --- a/src/net/tcp_connection.h +++ b/src/net/tcp_connection.h @@ -117,4 +117,3 @@ inline std::shared_ptr TcpConnection::GetContext() const { } } // namespace pikiwidb - diff --git a/src/net/unbounded_buffer.cc b/src/net/unbounded_buffer.cc index 81de183dc..33aa1328b 100644 --- a/src/net/unbounded_buffer.cc +++ b/src/net/unbounded_buffer.cc @@ -5,7 +5,6 @@ * of patent rights can be found in the PATENTS file in the same directory. */ - #include "unbounded_buffer.h" #include #include diff --git a/src/net/unbounded_buffer.h b/src/net/unbounded_buffer.h index df82370b8..eb8e6b9b6 100644 --- a/src/net/unbounded_buffer.h +++ b/src/net/unbounded_buffer.h @@ -5,7 +5,6 @@ * of patent rights can be found in the PATENTS file in the same directory. */ - #pragma once #include @@ -47,4 +46,3 @@ class UnboundedBuffer { }; } // namespace pikiwidb - diff --git a/src/net/util.h b/src/net/util.h index 409157816..92a12f76d 100644 --- a/src/net/util.h +++ b/src/net/util.h @@ -179,90 +179,54 @@ inline bool Probability(int percent) { return RandomBetween(1, 100 * 100) <= percent * 100; } -struct SocketAddr -{ - static const uint16_t kInvalidPort = -1; - - SocketAddr() - { - memset(&addr_, 0, sizeof addr_); - } - - SocketAddr(const sockaddr_in& addr) - { - Init(addr); - } - - SocketAddr(uint32_t netip, uint16_t netport) - { - Init(netip, netport); - } - - SocketAddr(const char* ip, uint16_t hostport) - { - Init(ip, hostport); - } - - void Init(const sockaddr_in& addr) - { - memcpy(&addr_, &addr, sizeof(addr)); - } - - void Init(uint32_t netip, uint16_t netport) - { - addr_.sin_family = AF_INET; - addr_.sin_addr.s_addr = netip; - addr_.sin_port = netport; - } - - void Init(const char* ip, uint16_t hostport) - { - addr_.sin_family = AF_INET; - addr_.sin_addr.s_addr = ::inet_addr(ip); - addr_.sin_port = htons(hostport); - } - - const sockaddr_in& GetAddr() const - { - return addr_; - } - - std::string GetIP() const - { - char tmp[32]; - const char* res = inet_ntop(AF_INET, &addr_.sin_addr, - tmp, (socklen_t)(sizeof tmp)); - return std::string(res); - } - - uint16_t GetPort() const - { - return ntohs(addr_.sin_port); - } - - bool IsValid() const { return addr_.sin_family != 0; } - - void Clear() - { - memset(&addr_, 0, sizeof addr_); - } - - inline friend bool operator== (const SocketAddr& a, const SocketAddr& b) - { - return a.addr_.sin_family == b.addr_.sin_family && - a.addr_.sin_addr.s_addr == b.addr_.sin_addr.s_addr && - a.addr_.sin_port == b.addr_.sin_port ; - } - - inline friend bool operator!= (const SocketAddr& a, const SocketAddr& b) - { - return !(a == b); - } - -private: - sockaddr_in addr_; -}; +struct SocketAddr { + static const uint16_t kInvalidPort = -1; + + SocketAddr() { memset(&addr_, 0, sizeof addr_); } + + SocketAddr(const sockaddr_in& addr) { Init(addr); } + + SocketAddr(uint32_t netip, uint16_t netport) { Init(netip, netport); } + + SocketAddr(const char* ip, uint16_t hostport) { Init(ip, hostport); } + + void Init(const sockaddr_in& addr) { memcpy(&addr_, &addr, sizeof(addr)); } + + void Init(uint32_t netip, uint16_t netport) { + addr_.sin_family = AF_INET; + addr_.sin_addr.s_addr = netip; + addr_.sin_port = netport; + } + + void Init(const char* ip, uint16_t hostport) { + addr_.sin_family = AF_INET; + addr_.sin_addr.s_addr = ::inet_addr(ip); + addr_.sin_port = htons(hostport); + } + const sockaddr_in& GetAddr() const { return addr_; } + std::string GetIP() const { + char tmp[32]; + const char* res = inet_ntop(AF_INET, &addr_.sin_addr, tmp, (socklen_t)(sizeof tmp)); + return std::string(res); + } + + uint16_t GetPort() const { return ntohs(addr_.sin_port); } + + bool IsValid() const { return addr_.sin_family != 0; } + + void Clear() { memset(&addr_, 0, sizeof addr_); } + + inline friend bool operator==(const SocketAddr& a, const SocketAddr& b) { + return a.addr_.sin_family == b.addr_.sin_family && a.addr_.sin_addr.s_addr == b.addr_.sin_addr.s_addr && + a.addr_.sin_port == b.addr_.sin_port; + } + + inline friend bool operator!=(const SocketAddr& a, const SocketAddr& b) { return !(a == b); } + + private: + sockaddr_in addr_; +}; } // namespace pikiwidb diff --git a/src/pikiwidb_logo.h b/src/pikiwidb_logo.h index d9e0e3a41..7cc5e5688 100644 --- a/src/pikiwidb_logo.h +++ b/src/pikiwidb_logo.h @@ -8,10 +8,9 @@ #pragma once const char* pikiwidbLogo = -"\n______ _ _ _ _ ______ ______ \n" - "| ___ \\ (_)| | (_) (_)| _ \\| ___ \\ \n" - "| |_/ / _ | | __ _ __ __ _ | | | || |_/ / PikiwiDB(%s) %d bits \n" // version and - "| __/ | || |/ /| |\\ \\ /\\ / /| || | | || ___ \\ \n" - "| | | || < | | \\ V V / | || |/ / | |_/ / Port: %d\n" - "\\_| |_||_|\\_\\|_| \\_/\\_/ |_||___/ \\____/ https://github.com/OpenAtomFoundation/pika \n\n\n"; - + "\n______ _ _ _ _ ______ ______ \n" + "| ___ \\ (_)| | (_) (_)| _ \\| ___ \\ \n" + "| |_/ / _ | | __ _ __ __ _ | | | || |_/ / PikiwiDB(%s) %d bits \n" // version and + "| __/ | || |/ /| |\\ \\ /\\ / /| || | | || ___ \\ \n" + "| | | || < | | \\ V V / | || |/ / | |_/ / Port: %d\n" + "\\_| |_||_|\\_\\|_| \\_/\\_/ |_||___/ \\____/ https://github.com/OpenAtomFoundation/pikiwidb \n\n\n"; diff --git a/src/pstd/thread_pool.cc b/src/pstd/thread_pool.cc index ef3e5c4c9..eed946353 100644 --- a/src/pstd/thread_pool.cc +++ b/src/pstd/thread_pool.cc @@ -107,4 +107,4 @@ void ThreadPool::_MonitorRoutine() { } } -} \ No newline at end of file +} // namespace pstd \ No newline at end of file diff --git a/src/pstring.h b/src/pstring.h index 3ba33eea8..bccec8c96 100644 --- a/src/pstring.h +++ b/src/pstring.h @@ -18,4 +18,3 @@ struct PObject; std::unique_ptr GetDecodedString(const PObject* value); } // namespace pikiwidb - diff --git a/src/pubsub.h b/src/pubsub.h index 3d2635228..5c5e988ad 100644 --- a/src/pubsub.h +++ b/src/pubsub.h @@ -55,4 +55,3 @@ class PPubsub { }; } // namespace pikiwidb - diff --git a/src/redis_intset.c b/src/redis_intset.c index 6d33779e4..9e7168d8b 100644 --- a/src/redis_intset.c +++ b/src/redis_intset.c @@ -31,13 +31,14 @@ #include #include #include + #include "redis_intset.h" -#define memrev16ifbe(x) (x) -#define memrev32ifbe(x) (x) -#define memrev64ifbe(x) (x) -#define intrev16ifbe(x) (x) -#define intrev32ifbe(x) (x) +#define memrev16ifbe(x) (x) +#define memrev32ifbe(x) (x) +#define memrev64ifbe(x) (x) +#define intrev16ifbe(x) (x) +#define intrev32ifbe(x) (x) /* Note that these encodings are ordered, so: * INTSET_ENC_INT16 < INTSET_ENC_INT32 < INTSET_ENC_INT64. */ @@ -47,69 +48,67 @@ /* Return the required encoding for the provided value. */ static uint8_t _intsetValueEncoding(int64_t v) { - if (v < INT32_MIN || v > INT32_MAX) - return INTSET_ENC_INT64; - else if (v < INT16_MIN || v > INT16_MAX) - return INTSET_ENC_INT32; - else - return INTSET_ENC_INT16; + if (v < INT32_MIN || v > INT32_MAX) + return INTSET_ENC_INT64; + else if (v < INT16_MIN || v > INT16_MAX) + return INTSET_ENC_INT32; + else + return INTSET_ENC_INT16; } /* Return the value at pos, given an encoding. */ static int64_t _intsetGetEncoded(intset *is, int pos, uint8_t enc) { - int64_t v64; - int32_t v32; - int16_t v16; - - if (enc == INTSET_ENC_INT64) { - memcpy(&v64,((int64_t*)is->contents)+pos,sizeof(v64)); - //memrev64ifbe(&v64); - return v64; - } else if (enc == INTSET_ENC_INT32) { - memcpy(&v32,((int32_t*)is->contents)+pos,sizeof(v32)); - //memrev32ifbe(&v32); - return v32; - } else { - memcpy(&v16,((int16_t*)is->contents)+pos,sizeof(v16)); - //memrev16ifbe(&v16); - return v16; - } + int64_t v64; + int32_t v32; + int16_t v16; + + if (enc == INTSET_ENC_INT64) { + memcpy(&v64, ((int64_t *)is->contents) + pos, sizeof(v64)); + // memrev64ifbe(&v64); + return v64; + } else if (enc == INTSET_ENC_INT32) { + memcpy(&v32, ((int32_t *)is->contents) + pos, sizeof(v32)); + // memrev32ifbe(&v32); + return v32; + } else { + memcpy(&v16, ((int16_t *)is->contents) + pos, sizeof(v16)); + // memrev16ifbe(&v16); + return v16; + } } /* Return the value at pos, using the configured encoding. */ -static int64_t _intsetGet(intset *is, int pos) { - return _intsetGetEncoded(is,pos,intrev32ifbe(is->encoding)); -} +static int64_t _intsetGet(intset *is, int pos) { return _intsetGetEncoded(is, pos, intrev32ifbe(is->encoding)); } /* Set the value at pos, using the configured encoding. */ static void _intsetSet(intset *is, int pos, int64_t value) { - uint32_t encoding = intrev32ifbe(is->encoding); - - if (encoding == INTSET_ENC_INT64) { - ((int64_t*)is->contents)[pos] = value; - //memrev64ifbe(((int64_t*)is->contents)+pos); - } else if (encoding == INTSET_ENC_INT32) { - ((int32_t*)is->contents)[pos] = (int32_t)value; - //memrev32ifbe(((int32_t*)is->contents)+pos); - } else { - ((int16_t*)is->contents)[pos] = (int16_t)value; - //memrev16ifbe(((int16_t*)is->contents)+pos); - } + uint32_t encoding = intrev32ifbe(is->encoding); + + if (encoding == INTSET_ENC_INT64) { + ((int64_t *)is->contents)[pos] = value; + // memrev64ifbe(((int64_t*)is->contents)+pos); + } else if (encoding == INTSET_ENC_INT32) { + ((int32_t *)is->contents)[pos] = (int32_t)value; + // memrev32ifbe(((int32_t*)is->contents)+pos); + } else { + ((int16_t *)is->contents)[pos] = (int16_t)value; + // memrev16ifbe(((int16_t*)is->contents)+pos); + } } /* Create an empty intset. */ intset *intsetNew(void) { - intset *is = malloc(sizeof(intset)); - is->encoding = intrev32ifbe(INTSET_ENC_INT16); - is->length = 0; - return is; + intset *is = malloc(sizeof(intset)); + is->encoding = intrev32ifbe(INTSET_ENC_INT16); + is->length = 0; + return is; } /* Resize the intset */ static intset *intsetResize(intset *is, uint32_t len) { - uint32_t size = len*intrev32ifbe(is->encoding); - is = realloc(is,sizeof(intset)+size); - return is; + uint32_t size = len * intrev32ifbe(is->encoding); + is = realloc(is, sizeof(intset) + size); + return is; } /* Search for the position of "value". Return 1 when the value was found and @@ -117,371 +116,374 @@ static intset *intsetResize(intset *is, uint32_t len) { * the value is not present in the intset and sets "pos" to the position * where "value" can be inserted. */ static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) { - int min = 0, max = intrev32ifbe(is->length)-1, mid = -1; - int64_t cur = -1; + int min = 0, max = intrev32ifbe(is->length) - 1, mid = -1; + int64_t cur = -1; - /* The value can never be found when the set is empty */ - if (intrev32ifbe(is->length) == 0) { - if (pos) *pos = 0; - return 0; - } else { - /* Check for the case where we know we cannot find the value, - * but do know the insert position. */ - if (value > _intsetGet(is,intrev32ifbe(is->length)-1)) { - if (pos) *pos = intrev32ifbe(is->length); - return 0; - } else if (value < _intsetGet(is,0)) { - if (pos) *pos = 0; - return 0; - } - } - - while(max >= min) { - mid = (min+max)/2; - cur = _intsetGet(is,mid); - if (value > cur) { - min = mid+1; - } else if (value < cur) { - max = mid-1; - } else { - break; - } + /* The value can never be found when the set is empty */ + if (intrev32ifbe(is->length) == 0) { + if (pos) *pos = 0; + return 0; + } else { + /* Check for the case where we know we cannot find the value, + * but do know the insert position. */ + if (value > _intsetGet(is, intrev32ifbe(is->length) - 1)) { + if (pos) *pos = intrev32ifbe(is->length); + return 0; + } else if (value < _intsetGet(is, 0)) { + if (pos) *pos = 0; + return 0; } - - if (value == cur) { - if (pos) *pos = mid; - return 1; + } + + while (max >= min) { + mid = (min + max) / 2; + cur = _intsetGet(is, mid); + if (value > cur) { + min = mid + 1; + } else if (value < cur) { + max = mid - 1; } else { - if (pos) *pos = min; - return 0; + break; } + } + + if (value == cur) { + if (pos) *pos = mid; + return 1; + } else { + if (pos) *pos = min; + return 0; + } } /* Upgrades the intset to a larger encoding and inserts the given integer. */ static intset *intsetUpgradeAndAdd(intset *is, int64_t value) { - uint8_t curenc = intrev32ifbe(is->encoding); - uint8_t newenc = _intsetValueEncoding(value); - int length = intrev32ifbe(is->length); - int prepend = value < 0 ? 1 : 0; - - /* First set new encoding and resize */ - is->encoding = intrev32ifbe(newenc); - is = intsetResize(is,intrev32ifbe(is->length)+1); - - /* Upgrade back-to-front so we don't overwrite values. - * Note that the "prepend" variable is used to make sure we have an empty - * space at either the beginning or the end of the intset. */ - while(length--) - _intsetSet(is,length+prepend,_intsetGetEncoded(is,length,curenc)); - - /* Set the value at the beginning or the end. */ - if (prepend) - _intsetSet(is,0,value); - else - _intsetSet(is,intrev32ifbe(is->length),value); - is->length = intrev32ifbe(intrev32ifbe(is->length)+1); - return is; + uint8_t curenc = intrev32ifbe(is->encoding); + uint8_t newenc = _intsetValueEncoding(value); + int length = intrev32ifbe(is->length); + int prepend = value < 0 ? 1 : 0; + + /* First set new encoding and resize */ + is->encoding = intrev32ifbe(newenc); + is = intsetResize(is, intrev32ifbe(is->length) + 1); + + /* Upgrade back-to-front so we don't overwrite values. + * Note that the "prepend" variable is used to make sure we have an empty + * space at either the beginning or the end of the intset. */ + while (length--) _intsetSet(is, length + prepend, _intsetGetEncoded(is, length, curenc)); + + /* Set the value at the beginning or the end. */ + if (prepend) + _intsetSet(is, 0, value); + else + _intsetSet(is, intrev32ifbe(is->length), value); + is->length = intrev32ifbe(intrev32ifbe(is->length) + 1); + return is; } static void intsetMoveTail(intset *is, uint32_t from, uint32_t to) { - void *src, *dst; - uint32_t bytes = intrev32ifbe(is->length)-from; - uint32_t encoding = intrev32ifbe(is->encoding); - - if (encoding == INTSET_ENC_INT64) { - src = (int64_t*)is->contents+from; - dst = (int64_t*)is->contents+to; - bytes *= sizeof(int64_t); - } else if (encoding == INTSET_ENC_INT32) { - src = (int32_t*)is->contents+from; - dst = (int32_t*)is->contents+to; - bytes *= sizeof(int32_t); - } else { - src = (int16_t*)is->contents+from; - dst = (int16_t*)is->contents+to; - bytes *= sizeof(int16_t); - } - memmove(dst,src,bytes); + void *src, *dst; + uint32_t bytes = intrev32ifbe(is->length) - from; + uint32_t encoding = intrev32ifbe(is->encoding); + + if (encoding == INTSET_ENC_INT64) { + src = (int64_t *)is->contents + from; + dst = (int64_t *)is->contents + to; + bytes *= sizeof(int64_t); + } else if (encoding == INTSET_ENC_INT32) { + src = (int32_t *)is->contents + from; + dst = (int32_t *)is->contents + to; + bytes *= sizeof(int32_t); + } else { + src = (int16_t *)is->contents + from; + dst = (int16_t *)is->contents + to; + bytes *= sizeof(int16_t); + } + memmove(dst, src, bytes); } /* Insert an integer in the intset */ intset *intsetAdd(intset *is, int64_t value, uint8_t *success) { - uint8_t valenc = _intsetValueEncoding(value); - uint32_t pos; - if (success) *success = 1; - - /* Upgrade encoding if necessary. If we need to upgrade, we know that - * this value should be either appended (if > 0) or prepended (if < 0), - * because it lies outside the range of existing values. */ - if (valenc > intrev32ifbe(is->encoding)) { - /* This always succeeds, so we don't need to curry *success. */ - return intsetUpgradeAndAdd(is,value); - } else { - /* Abort if the value is already present in the set. - * This call will populate "pos" with the right position to insert - * the value when it cannot be found. */ - if (intsetSearch(is,value,&pos)) { - if (success) *success = 0; - return is; - } - - is = intsetResize(is,intrev32ifbe(is->length)+1); - if (pos < intrev32ifbe(is->length)) intsetMoveTail(is,pos,pos+1); + uint8_t valenc = _intsetValueEncoding(value); + uint32_t pos; + if (success) *success = 1; + + /* Upgrade encoding if necessary. If we need to upgrade, we know that + * this value should be either appended (if > 0) or prepended (if < 0), + * because it lies outside the range of existing values. */ + if (valenc > intrev32ifbe(is->encoding)) { + /* This always succeeds, so we don't need to curry *success. */ + return intsetUpgradeAndAdd(is, value); + } else { + /* Abort if the value is already present in the set. + * This call will populate "pos" with the right position to insert + * the value when it cannot be found. */ + if (intsetSearch(is, value, &pos)) { + if (success) *success = 0; + return is; } - _intsetSet(is,pos,value); - is->length = intrev32ifbe(intrev32ifbe(is->length)+1); - return is; + is = intsetResize(is, intrev32ifbe(is->length) + 1); + if (pos < intrev32ifbe(is->length)) intsetMoveTail(is, pos, pos + 1); + } + + _intsetSet(is, pos, value); + is->length = intrev32ifbe(intrev32ifbe(is->length) + 1); + return is; } /* Delete integer from intset */ intset *intsetRemove(intset *is, int64_t value, int *success) { - uint8_t valenc = _intsetValueEncoding(value); - uint32_t pos; - if (success) *success = 0; + uint8_t valenc = _intsetValueEncoding(value); + uint32_t pos; + if (success) *success = 0; - if (valenc <= intrev32ifbe(is->encoding) && intsetSearch(is,value,&pos)) { - uint32_t len = intrev32ifbe(is->length); + if (valenc <= intrev32ifbe(is->encoding) && intsetSearch(is, value, &pos)) { + uint32_t len = intrev32ifbe(is->length); - /* We know we can delete */ - if (success) *success = 1; + /* We know we can delete */ + if (success) *success = 1; - /* Overwrite value with tail and update length */ - if (pos < (len-1)) intsetMoveTail(is,pos+1,pos); - is = intsetResize(is,len-1); - is->length = intrev32ifbe(len-1); - } - return is; + /* Overwrite value with tail and update length */ + if (pos < (len - 1)) intsetMoveTail(is, pos + 1, pos); + is = intsetResize(is, len - 1); + is->length = intrev32ifbe(len - 1); + } + return is; } /* Determine whether a value belongs to this set */ uint8_t intsetFind(intset *is, int64_t value) { - uint8_t valenc = _intsetValueEncoding(value); - return valenc <= intrev32ifbe(is->encoding) && intsetSearch(is,value,NULL); + uint8_t valenc = _intsetValueEncoding(value); + return valenc <= intrev32ifbe(is->encoding) && intsetSearch(is, value, NULL); } /* Return random member */ -int64_t intsetRandom(intset *is) { - return _intsetGet(is,rand()%intrev32ifbe(is->length)); -} +int64_t intsetRandom(intset *is) { return _intsetGet(is, rand() % intrev32ifbe(is->length)); } /* Sets the value to the value at the given position. When this position is * out of range the function returns 0, when in range it returns 1. */ uint8_t intsetGet(intset *is, uint32_t pos, int64_t *value) { - if (pos < intrev32ifbe(is->length)) { - *value = _intsetGet(is,pos); - return 1; - } - return 0; + if (pos < intrev32ifbe(is->length)) { + *value = _intsetGet(is, pos); + return 1; + } + return 0; } /* Return intset length */ -uint32_t intsetLen(intset *is) { - return intrev32ifbe(is->length); -} +uint32_t intsetLen(intset *is) { return intrev32ifbe(is->length); } /* Return intset blob size in bytes. */ -size_t intsetBlobLen(intset *is) { - return sizeof(intset)+intrev32ifbe(is->length)*intrev32ifbe(is->encoding); -} +size_t intsetBlobLen(intset *is) { return sizeof(intset) + intrev32ifbe(is->length) * intrev32ifbe(is->encoding); } #ifdef INTSET_TEST_MAIN -#include +# include void intsetRepr(intset *is) { - int i; - for (i = 0; i < intrev32ifbe(is->length); i++) { - printf("%lld\n", (uint64_t)_intsetGet(is,i)); - } - printf("\n"); + int i; + for (i = 0; i < intrev32ifbe(is->length); i++) { + printf("%lld\n", (uint64_t)_intsetGet(is, i)); + } + printf("\n"); } void error(char *err) { - printf("%s\n", err); - exit(1); + printf("%s\n", err); + exit(1); } -void ok(void) { - printf("OK\n"); -} +void ok(void) { printf("OK\n"); } long long usec(void) { - struct timeval tv; - gettimeofday(&tv,NULL); - return (((long long)tv.tv_sec)*1000000)+tv.tv_usec; + struct timeval tv; + gettimeofday(&tv, NULL); + return (((long long)tv.tv_sec) * 1000000) + tv.tv_usec; } -#define assert(_e) ((_e)?(void)0:(_assert(#_e,__FILE__,__LINE__),exit(1))) +# define assert(_e) ((_e) ? (void)0 : (_assert(# _e, __FILE__, __LINE__), exit(1))) void _assert(char *estr, char *file, int line) { - printf("\n\n=== ASSERTION FAILED ===\n"); - printf("==> %s:%d '%s' is not true\n",file,line,estr); + printf("\n\n=== ASSERTION FAILED ===\n"); + printf("==> %s:%d '%s' is not true\n", file, line, estr); } intset *createSet(int bits, int size) { - uint64_t mask = (1< 32) { - value = (rand()*rand()) & mask; - } else { - value = rand() & mask; - } - is = intsetAdd(is,value,NULL); - } - return is; -} + uint64_t mask = (1 << bits) - 1; + uint64_t i, value; + intset *is = intsetNew(); -void checkConsistency(intset *is) { - int i; - - for (i = 0; i < (intrev32ifbe(is->length)-1); i++) { - uint32_t encoding = intrev32ifbe(is->encoding); - - if (encoding == INTSET_ENC_INT16) { - int16_t *i16 = (int16_t*)is->contents; - assert(i16[i] < i16[i+1]); - } else if (encoding == INTSET_ENC_INT32) { - int32_t *i32 = (int32_t*)is->contents; - assert(i32[i] < i32[i+1]); - } else { - int64_t *i64 = (int64_t*)is->contents; - assert(i64[i] < i64[i+1]); - } + for (i = 0; i < size; i++) { + if (bits > 32) { + value = (rand() * rand()) & mask; + } else { + value = rand() & mask; } + is = intsetAdd(is, value, NULL); + } + return is; } -int main(int argc, char **argv) { - uint8_t success; - int i; - intset *is; - sranddev(); - - printf("Value encodings: "); { - assert(_intsetValueEncoding(-32768) == INTSET_ENC_INT16); - assert(_intsetValueEncoding(+32767) == INTSET_ENC_INT16); - assert(_intsetValueEncoding(-32769) == INTSET_ENC_INT32); - assert(_intsetValueEncoding(+32768) == INTSET_ENC_INT32); - assert(_intsetValueEncoding(-2147483648) == INTSET_ENC_INT32); - assert(_intsetValueEncoding(+2147483647) == INTSET_ENC_INT32); - assert(_intsetValueEncoding(-2147483649) == INTSET_ENC_INT64); - assert(_intsetValueEncoding(+2147483648) == INTSET_ENC_INT64); - assert(_intsetValueEncoding(-9223372036854775808ull) == INTSET_ENC_INT64); - assert(_intsetValueEncoding(+9223372036854775807ull) == INTSET_ENC_INT64); - ok(); - } - - printf("Basic adding: "); { - is = intsetNew(); - is = intsetAdd(is,5,&success); assert(success); - is = intsetAdd(is,6,&success); assert(success); - is = intsetAdd(is,4,&success); assert(success); - is = intsetAdd(is,4,&success); assert(!success); - ok(); - } - - printf("Large number of random adds: "); { - int inserts = 0; - is = intsetNew(); - for (i = 0; i < 1024; i++) { - is = intsetAdd(is,rand()%0x800,&success); - if (success) inserts++; - } - assert(intrev32ifbe(is->length) == inserts); - checkConsistency(is); - ok(); - } - - printf("Upgrade from int16 to int32: "); { - is = intsetNew(); - is = intsetAdd(is,32,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16); - is = intsetAdd(is,65535,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32); - assert(intsetFind(is,32)); - assert(intsetFind(is,65535)); - checkConsistency(is); - - is = intsetNew(); - is = intsetAdd(is,32,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16); - is = intsetAdd(is,-65535,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32); - assert(intsetFind(is,32)); - assert(intsetFind(is,-65535)); - checkConsistency(is); - ok(); - } +void checkConsistency(intset *is) { + int i; - printf("Upgrade from int16 to int64: "); { - is = intsetNew(); - is = intsetAdd(is,32,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16); - is = intsetAdd(is,4294967295,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64); - assert(intsetFind(is,32)); - assert(intsetFind(is,4294967295)); - checkConsistency(is); - - is = intsetNew(); - is = intsetAdd(is,32,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16); - is = intsetAdd(is,-4294967295,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64); - assert(intsetFind(is,32)); - assert(intsetFind(is,-4294967295)); - checkConsistency(is); - ok(); - } + for (i = 0; i < (intrev32ifbe(is->length) - 1); i++) { + uint32_t encoding = intrev32ifbe(is->encoding); - printf("Upgrade from int32 to int64: "); { - is = intsetNew(); - is = intsetAdd(is,65535,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32); - is = intsetAdd(is,4294967295,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64); - assert(intsetFind(is,65535)); - assert(intsetFind(is,4294967295)); - checkConsistency(is); - - is = intsetNew(); - is = intsetAdd(is,65535,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32); - is = intsetAdd(is,-4294967295,NULL); - assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64); - assert(intsetFind(is,65535)); - assert(intsetFind(is,-4294967295)); - checkConsistency(is); - ok(); + if (encoding == INTSET_ENC_INT16) { + int16_t *i16 = (int16_t *)is->contents; + assert(i16[i] < i16[i + 1]); + } else if (encoding == INTSET_ENC_INT32) { + int32_t *i32 = (int32_t *)is->contents; + assert(i32[i] < i32[i + 1]); + } else { + int64_t *i64 = (int64_t *)is->contents; + assert(i64[i] < i64[i + 1]); } + } +} - printf("Stress lookups: "); { - long num = 100000, size = 10000; - int i, bits = 20; - long long start; - is = createSet(bits,size); - checkConsistency(is); - - start = usec(); - for (i = 0; i < num; i++) intsetSearch(is,rand() % ((1<length) == inserts); + checkConsistency(is); + ok(); + } + + printf("Upgrade from int16 to int32: "); + { + is = intsetNew(); + is = intsetAdd(is, 32, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16); + is = intsetAdd(is, 65535, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32); + assert(intsetFind(is, 32)); + assert(intsetFind(is, 65535)); + checkConsistency(is); + + is = intsetNew(); + is = intsetAdd(is, 32, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16); + is = intsetAdd(is, -65535, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32); + assert(intsetFind(is, 32)); + assert(intsetFind(is, -65535)); + checkConsistency(is); + ok(); + } + + printf("Upgrade from int16 to int64: "); + { + is = intsetNew(); + is = intsetAdd(is, 32, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16); + is = intsetAdd(is, 4294967295, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64); + assert(intsetFind(is, 32)); + assert(intsetFind(is, 4294967295)); + checkConsistency(is); + + is = intsetNew(); + is = intsetAdd(is, 32, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT16); + is = intsetAdd(is, -4294967295, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64); + assert(intsetFind(is, 32)); + assert(intsetFind(is, -4294967295)); + checkConsistency(is); + ok(); + } + + printf("Upgrade from int32 to int64: "); + { + is = intsetNew(); + is = intsetAdd(is, 65535, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32); + is = intsetAdd(is, 4294967295, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64); + assert(intsetFind(is, 65535)); + assert(intsetFind(is, 4294967295)); + checkConsistency(is); + + is = intsetNew(); + is = intsetAdd(is, 65535, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT32); + is = intsetAdd(is, -4294967295, NULL); + assert(intrev32ifbe(is->encoding) == INTSET_ENC_INT64); + assert(intsetFind(is, 65535)); + assert(intsetFind(is, -4294967295)); + checkConsistency(is); + ok(); + } + + printf("Stress lookups: "); + { + long num = 100000, size = 10000; + int i, bits = 20; + long long start; + is = createSet(bits, size); + checkConsistency(is); + + start = usec(); + for (i = 0; i < num; i++) intsetSearch(is, rand() % ((1 << bits) - 1), NULL); + printf("%ld lookups, %ld element set, %lldusec\n", num, size, usec() - start); + } + + printf("Stress add+delete: "); + { + int i, v1, v2; + is = intsetNew(); + for (i = 0; i < 0xffff; i++) { + v1 = rand() % 0xfff; + is = intsetAdd(is, v1, NULL); + assert(intsetFind(is, v1)); + + v2 = rand() % 0xfff; + is = intsetRemove(is, v2, NULL); + assert(!intsetFind(is, v2)); } + checkConsistency(is); + ok(); + } } #endif diff --git a/src/redis_intset.h b/src/redis_intset.h index 44d6f9a56..f18f7511a 100644 --- a/src/redis_intset.h +++ b/src/redis_intset.h @@ -39,9 +39,9 @@ #include typedef struct intset { - uint32_t encoding; - uint32_t length; - int8_t contents[]; + uint32_t encoding; + uint32_t length; + int8_t contents[]; } intset; intset *intsetNew(void); diff --git a/src/redis_zip_list.c b/src/redis_zip_list.c index cc1ff55fd..a4a40ac3c 100644 --- a/src/redis_zip_list.c +++ b/src/redis_zip_list.c @@ -101,17 +101,18 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include +#include #include #include #include -#include -#include -#include + #include "redis_zip_list.h" -#define memrev32ifbe(x) (x) -#define intrev32ifbe(x) (x) -#define intrev16ifbe(x) (x) +#define memrev32ifbe(x) (x) +#define intrev32ifbe(x) (x) +#define intrev16ifbe(x) (x) #define ZIP_END 255 #define ZIP_BIGLEN 254 @@ -122,15 +123,15 @@ #define ZIP_STR_06B (0 << 6) #define ZIP_STR_14B (1 << 6) #define ZIP_STR_32B (2 << 6) -#define ZIP_INT_16B (0xc0 | 0<<4) -#define ZIP_INT_32B (0xc0 | 1<<4) -#define ZIP_INT_64B (0xc0 | 2<<4) -#define ZIP_INT_24B (0xc0 | 3<<4) +#define ZIP_INT_16B (0xc0 | 0 << 4) +#define ZIP_INT_32B (0xc0 | 1 << 4) +#define ZIP_INT_64B (0xc0 | 2 << 4) +#define ZIP_INT_24B (0xc0 | 3 << 4) #define ZIP_INT_8B 0xfe /* 4 bit integer immediate encoding */ #define ZIP_INT_IMM_MASK 0x0f -#define ZIP_INT_IMM_MIN 0xf1 /* 11110001 */ -#define ZIP_INT_IMM_MAX 0xfd /* 11111101 */ +#define ZIP_INT_IMM_MIN 0xf1 /* 11110001 */ +#define ZIP_INT_IMM_MAX 0xfd /* 11111101 */ #define ZIP_INT_IMM_VAL(v) (v & ZIP_INT_IMM_MASK) #define INT24_MAX 0x7fffff @@ -140,309 +141,314 @@ #define ZIP_IS_STR(enc) (((enc) & ZIP_STR_MASK) < ZIP_STR_MASK) /* Utility macros */ -#define ZIPLIST_BYTES(zl) (*((uint32_t*)(zl))) -#define ZIPLIST_TAIL_OFFSET(zl) (*((uint32_t*)((zl)+sizeof(uint32_t)))) -#define ZIPLIST_LENGTH(zl) (*((uint16_t*)((zl)+sizeof(uint32_t)*2))) -#define ZIPLIST_HEADER_SIZE (sizeof(uint32_t)*2+sizeof(uint16_t)) -#define ZIPLIST_ENTRY_HEAD(zl) ((zl)+ZIPLIST_HEADER_SIZE) -#define ZIPLIST_ENTRY_TAIL(zl) ((zl)+intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))) -#define ZIPLIST_ENTRY_END(zl) ((zl)+intrev32ifbe(ZIPLIST_BYTES(zl))-1) +#define ZIPLIST_BYTES(zl) (*((uint32_t *)(zl))) +#define ZIPLIST_TAIL_OFFSET(zl) (*((uint32_t *)((zl) + sizeof(uint32_t)))) +#define ZIPLIST_LENGTH(zl) (*((uint16_t *)((zl) + sizeof(uint32_t) * 2))) +#define ZIPLIST_HEADER_SIZE (sizeof(uint32_t) * 2 + sizeof(uint16_t)) +#define ZIPLIST_ENTRY_HEAD(zl) ((zl) + ZIPLIST_HEADER_SIZE) +#define ZIPLIST_ENTRY_TAIL(zl) ((zl) + intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))) +#define ZIPLIST_ENTRY_END(zl) ((zl) + intrev32ifbe(ZIPLIST_BYTES(zl)) - 1) /* We know a positive increment can only be 1 because entries can only be * pushed one at a time. */ -#define ZIPLIST_INCR_LENGTH(zl,incr) { \ - if (ZIPLIST_LENGTH(zl) < UINT16_MAX) \ - ZIPLIST_LENGTH(zl) = intrev16ifbe(intrev16ifbe(ZIPLIST_LENGTH(zl))+incr); \ -} +#define ZIPLIST_INCR_LENGTH(zl, incr) \ + { \ + if (ZIPLIST_LENGTH(zl) < UINT16_MAX) ZIPLIST_LENGTH(zl) = intrev16ifbe(intrev16ifbe(ZIPLIST_LENGTH(zl)) + incr); \ + } typedef struct zlentry { - unsigned int prevrawlensize, prevrawlen; - unsigned int lensize, len; - unsigned int headersize; - unsigned char encoding; - unsigned char *p; + unsigned int prevrawlensize, prevrawlen; + unsigned int lensize, len; + unsigned int headersize; + unsigned char encoding; + unsigned char *p; } zlentry; /* Extract the encoding from the byte pointed by 'ptr' and set it into * 'encoding'. */ -#define ZIP_ENTRY_ENCODING(ptr, encoding) do { \ - (encoding) = (ptr[0]); \ +#define ZIP_ENTRY_ENCODING(ptr, encoding) \ + do { \ + (encoding) = (ptr[0]); \ if ((encoding) < ZIP_STR_MASK) (encoding) &= ZIP_STR_MASK; \ -} while(0) + } while (0) /* Return bytes needed to store integer encoded by 'encoding' */ static unsigned int zipIntSize(unsigned char encoding) { - switch(encoding) { - case ZIP_INT_8B: return 1; - case ZIP_INT_16B: return 2; - case ZIP_INT_24B: return 3; - case ZIP_INT_32B: return 4; - case ZIP_INT_64B: return 8; - default: return 0; /* 4 bit immediate */ - } - assert(NULL); - return 0; + switch (encoding) { + case ZIP_INT_8B: + return 1; + case ZIP_INT_16B: + return 2; + case ZIP_INT_24B: + return 3; + case ZIP_INT_32B: + return 4; + case ZIP_INT_64B: + return 8; + default: + return 0; /* 4 bit immediate */ + } + assert(NULL); + return 0; } /* Encode the length 'l' writing it in 'p'. If p is NULL it just returns * the amount of bytes required to encode such a length. */ static unsigned int zipEncodeLength(unsigned char *p, unsigned char encoding, unsigned int rawlen) { - unsigned char len = 1, buf[5]; - - if (ZIP_IS_STR(encoding)) { - /* Although encoding is given it may not be set for strings, - * so we determine it here using the raw length. */ - if (rawlen <= 0x3f) { - if (!p) return len; - buf[0] = ZIP_STR_06B | rawlen; - } else if (rawlen <= 0x3fff) { - len += 1; - if (!p) return len; - buf[0] = ZIP_STR_14B | ((rawlen >> 8) & 0x3f); - buf[1] = rawlen & 0xff; - } else { - len += 4; - if (!p) return len; - buf[0] = ZIP_STR_32B; - buf[1] = (rawlen >> 24) & 0xff; - buf[2] = (rawlen >> 16) & 0xff; - buf[3] = (rawlen >> 8) & 0xff; - buf[4] = rawlen & 0xff; - } + unsigned char len = 1, buf[5]; + + if (ZIP_IS_STR(encoding)) { + /* Although encoding is given it may not be set for strings, + * so we determine it here using the raw length. */ + if (rawlen <= 0x3f) { + if (!p) return len; + buf[0] = ZIP_STR_06B | rawlen; + } else if (rawlen <= 0x3fff) { + len += 1; + if (!p) return len; + buf[0] = ZIP_STR_14B | ((rawlen >> 8) & 0x3f); + buf[1] = rawlen & 0xff; } else { - /* Implies integer encoding, so length is always 1. */ - if (!p) return len; - buf[0] = encoding; + len += 4; + if (!p) return len; + buf[0] = ZIP_STR_32B; + buf[1] = (rawlen >> 24) & 0xff; + buf[2] = (rawlen >> 16) & 0xff; + buf[3] = (rawlen >> 8) & 0xff; + buf[4] = rawlen & 0xff; } - - /* Store this length at p */ - memcpy(p,buf,len); - return len; + } else { + /* Implies integer encoding, so length is always 1. */ + if (!p) return len; + buf[0] = encoding; + } + + /* Store this length at p */ + memcpy(p, buf, len); + return len; } /* Decode the length encoded in 'ptr'. The 'encoding' variable will hold the * entries encoding, the 'lensize' variable will hold the number of bytes * required to encode the entries length, and the 'len' variable will hold the * entries length. */ -#define ZIP_DECODE_LENGTH(ptr, encoding, lensize, len) do { \ - ZIP_ENTRY_ENCODING((ptr), (encoding)); \ - if ((encoding) < ZIP_STR_MASK) { \ - if ((encoding) == ZIP_STR_06B) { \ - (lensize) = 1; \ - (len) = (ptr)[0] & 0x3f; \ - } else if ((encoding) == ZIP_STR_14B) { \ - (lensize) = 2; \ - (len) = (((ptr)[0] & 0x3f) << 8) | (ptr)[1]; \ - } else if (encoding == ZIP_STR_32B) { \ - (lensize) = 5; \ - (len) = ((ptr)[1] << 24) | \ - ((ptr)[2] << 16) | \ - ((ptr)[3] << 8) | \ - ((ptr)[4]); \ - } else { \ - assert(NULL); \ - } \ - } else { \ - (lensize) = 1; \ - (len) = zipIntSize(encoding); \ - } \ -} while(0); +#define ZIP_DECODE_LENGTH(ptr, encoding, lensize, len) \ + do { \ + ZIP_ENTRY_ENCODING((ptr), (encoding)); \ + if ((encoding) < ZIP_STR_MASK) { \ + if ((encoding) == ZIP_STR_06B) { \ + (lensize) = 1; \ + (len) = (ptr)[0] & 0x3f; \ + } else if ((encoding) == ZIP_STR_14B) { \ + (lensize) = 2; \ + (len) = (((ptr)[0] & 0x3f) << 8) | (ptr)[1]; \ + } else if (encoding == ZIP_STR_32B) { \ + (lensize) = 5; \ + (len) = ((ptr)[1] << 24) | ((ptr)[2] << 16) | ((ptr)[3] << 8) | ((ptr)[4]); \ + } else { \ + assert(NULL); \ + } \ + } else { \ + (lensize) = 1; \ + (len) = zipIntSize(encoding); \ + } \ + } while (0); /* Encode the length of the previous entry and write it to "p". Return the * number of bytes needed to encode this length if "p" is NULL. */ static unsigned int zipPrevEncodeLength(unsigned char *p, unsigned int len) { - if (p == NULL) { - return (len < ZIP_BIGLEN) ? 1 : sizeof(len)+1; + if (p == NULL) { + return (len < ZIP_BIGLEN) ? 1 : sizeof(len) + 1; + } else { + if (len < ZIP_BIGLEN) { + p[0] = len; + return 1; } else { - if (len < ZIP_BIGLEN) { - p[0] = len; - return 1; - } else { - p[0] = ZIP_BIGLEN; - memcpy(p+1,&len,sizeof(len)); - //memrev32ifbe(p+1); - return 1+sizeof(len); - } + p[0] = ZIP_BIGLEN; + memcpy(p + 1, &len, sizeof(len)); + // memrev32ifbe(p+1); + return 1 + sizeof(len); } + } } /* Encode the length of the previous entry and write it to "p". This only * uses the larger encoding (required in __ziplistCascadeUpdate). */ static void zipPrevEncodeLengthForceLarge(unsigned char *p, unsigned int len) { - if (p == NULL) return; - p[0] = ZIP_BIGLEN; - memcpy(p+1,&len,sizeof(len)); - // memrev32ifbe(p+1); + if (p == NULL) return; + p[0] = ZIP_BIGLEN; + memcpy(p + 1, &len, sizeof(len)); + // memrev32ifbe(p+1); } /* Decode the number of bytes required to store the length of the previous * element, from the perspective of the entry pointed to by 'ptr'. */ -#define ZIP_DECODE_PREVLENSIZE(ptr, prevlensize) do { \ - if ((ptr)[0] < ZIP_BIGLEN) { \ - (prevlensize) = 1; \ - } else { \ - (prevlensize) = 5; \ - } \ -} while(0); +#define ZIP_DECODE_PREVLENSIZE(ptr, prevlensize) \ + do { \ + if ((ptr)[0] < ZIP_BIGLEN) { \ + (prevlensize) = 1; \ + } else { \ + (prevlensize) = 5; \ + } \ + } while (0); /* Decode the length of the previous element, from the perspective of the entry * pointed to by 'ptr'. */ -#define ZIP_DECODE_PREVLEN(ptr, prevlensize, prevlen) do { \ - ZIP_DECODE_PREVLENSIZE(ptr, prevlensize); \ - if ((prevlensize) == 1) { \ - (prevlen) = (ptr)[0]; \ - } else if ((prevlensize) == 5) { \ - assert(sizeof((prevlensize)) == 4); \ - memcpy(&(prevlen), ((char*)(ptr)) + 1, 4); \ - } \ -} while(0); +#define ZIP_DECODE_PREVLEN(ptr, prevlensize, prevlen) \ + do { \ + ZIP_DECODE_PREVLENSIZE(ptr, prevlensize); \ + if ((prevlensize) == 1) { \ + (prevlen) = (ptr)[0]; \ + } else if ((prevlensize) == 5) { \ + assert(sizeof((prevlensize)) == 4); \ + memcpy(&(prevlen), ((char *)(ptr)) + 1, 4); \ + } \ + } while (0); /* Return the difference in number of bytes needed to store the length of the * previous element 'len', in the entry pointed to by 'p'. */ static int zipPrevLenByteDiff(unsigned char *p, unsigned int len) { - unsigned int prevlensize; - ZIP_DECODE_PREVLENSIZE(p, prevlensize); - return zipPrevEncodeLength(NULL, len) - prevlensize; + unsigned int prevlensize; + ZIP_DECODE_PREVLENSIZE(p, prevlensize); + return zipPrevEncodeLength(NULL, len) - prevlensize; } /* Return the total number of bytes used by the entry pointed to by 'p'. */ static unsigned int zipRawEntryLength(unsigned char *p) { - unsigned int prevlensize, encoding, lensize, len; - ZIP_DECODE_PREVLENSIZE(p, prevlensize); - ZIP_DECODE_LENGTH(p + prevlensize, encoding, lensize, len); - return prevlensize + lensize + len; + unsigned int prevlensize, encoding, lensize, len; + ZIP_DECODE_PREVLENSIZE(p, prevlensize); + ZIP_DECODE_LENGTH(p + prevlensize, encoding, lensize, len); + return prevlensize + lensize + len; } -int Strtoll(const char* ptr, size_t nBytes, long long* outVal) -{ - if (nBytes == 0 || nBytes > 21) - return 0; - - char* pEnd = 0; - long long ret = strtoll(ptr, &pEnd, 0); - - *outVal = ret; - return pEnd == ptr + nBytes; +int Strtoll(const char *ptr, size_t nBytes, long long *outVal) { + if (nBytes == 0 || nBytes > 21) return 0; + + char *pEnd = 0; + long long ret = strtoll(ptr, &pEnd, 0); + + *outVal = ret; + return pEnd == ptr + nBytes; } /* Check if string pointed to by 'entry' can be encoded as an integer. * Stores the integer value in 'v' and its encoding in 'encoding'. */ static int zipTryEncoding(unsigned char *entry, unsigned int entrylen, long long *v, unsigned char *encoding) { - long long value; - - if (entrylen >= 32 || entrylen == 0) return 0; - if (Strtoll((const char*)entry, entrylen, &value)) { - /* Great, the string can be encoded. Check what's the smallest - * of our encoding types that can hold this value. */ - if (value >= 0 && value <= 12) { - *encoding = ZIP_INT_IMM_MIN+value; - } else if (value >= INT8_MIN && value <= INT8_MAX) { - *encoding = ZIP_INT_8B; - } else if (value >= INT16_MIN && value <= INT16_MAX) { - *encoding = ZIP_INT_16B; - } else if (value >= INT24_MIN && value <= INT24_MAX) { - *encoding = ZIP_INT_24B; - } else if (value >= INT32_MIN && value <= INT32_MAX) { - *encoding = ZIP_INT_32B; - } else { - *encoding = ZIP_INT_64B; - } - *v = value; - return 1; + long long value; + + if (entrylen >= 32 || entrylen == 0) return 0; + if (Strtoll((const char *)entry, entrylen, &value)) { + /* Great, the string can be encoded. Check what's the smallest + * of our encoding types that can hold this value. */ + if (value >= 0 && value <= 12) { + *encoding = ZIP_INT_IMM_MIN + value; + } else if (value >= INT8_MIN && value <= INT8_MAX) { + *encoding = ZIP_INT_8B; + } else if (value >= INT16_MIN && value <= INT16_MAX) { + *encoding = ZIP_INT_16B; + } else if (value >= INT24_MIN && value <= INT24_MAX) { + *encoding = ZIP_INT_24B; + } else if (value >= INT32_MIN && value <= INT32_MAX) { + *encoding = ZIP_INT_32B; + } else { + *encoding = ZIP_INT_64B; } - return 0; + *v = value; + return 1; + } + return 0; } /* Store integer 'value' at 'p', encoded as 'encoding' */ static void zipSaveInteger(unsigned char *p, int64_t value, unsigned char encoding) { - int16_t i16; - int32_t i32; - int64_t i64; - if (encoding == ZIP_INT_8B) { - ((int8_t*)p)[0] = (int8_t)value; - } else if (encoding == ZIP_INT_16B) { - i16 = value; - memcpy(p,&i16,sizeof(i16)); - //memrev16ifbe(p); - } else if (encoding == ZIP_INT_24B) { - i32 = (int32_t)(value<<8); - //memrev32ifbe(&i32); - memcpy(p,((uint8_t*)&i32)+1,sizeof(i32)-sizeof(uint8_t)); - } else if (encoding == ZIP_INT_32B) { - i32 = (int32_t)(value); - memcpy(p,&i32,sizeof(i32)); - // memrev32ifbe(p); - } else if (encoding == ZIP_INT_64B) { - i64 = value; - memcpy(p,&i64,sizeof(i64)); - //memrev64ifbe(p); - } else if (encoding >= ZIP_INT_IMM_MIN && encoding <= ZIP_INT_IMM_MAX) { - /* Nothing to do, the value is stored in the encoding itself. */ - } else { - assert(NULL); - } + int16_t i16; + int32_t i32; + int64_t i64; + if (encoding == ZIP_INT_8B) { + ((int8_t *)p)[0] = (int8_t)value; + } else if (encoding == ZIP_INT_16B) { + i16 = value; + memcpy(p, &i16, sizeof(i16)); + // memrev16ifbe(p); + } else if (encoding == ZIP_INT_24B) { + i32 = (int32_t)(value << 8); + // memrev32ifbe(&i32); + memcpy(p, ((uint8_t *)&i32) + 1, sizeof(i32) - sizeof(uint8_t)); + } else if (encoding == ZIP_INT_32B) { + i32 = (int32_t)(value); + memcpy(p, &i32, sizeof(i32)); + // memrev32ifbe(p); + } else if (encoding == ZIP_INT_64B) { + i64 = value; + memcpy(p, &i64, sizeof(i64)); + // memrev64ifbe(p); + } else if (encoding >= ZIP_INT_IMM_MIN && encoding <= ZIP_INT_IMM_MAX) { + /* Nothing to do, the value is stored in the encoding itself. */ + } else { + assert(NULL); + } } /* Read integer encoded as 'encoding' from 'p' */ static int64_t zipLoadInteger(unsigned char *p, unsigned char encoding) { - int16_t i16; - int32_t i32; - int64_t i64, ret = 0; - if (encoding == ZIP_INT_8B) { - ret = ((int8_t*)p)[0]; - } else if (encoding == ZIP_INT_16B) { - memcpy(&i16,p,sizeof(i16)); - // memrev16ifbe(&i16); - ret = i16; - } else if (encoding == ZIP_INT_32B) { - memcpy(&i32,p,sizeof(i32)); - // memrev32ifbe(&i32); - ret = i32; - } else if (encoding == ZIP_INT_24B) { - i32 = 0; - memcpy(((uint8_t*)&i32)+1,p,sizeof(i32)-sizeof(uint8_t)); - // memrev32ifbe(&i32); - ret = i32>>8; - } else if (encoding == ZIP_INT_64B) { - memcpy(&i64,p,sizeof(i64)); - // memrev64ifbe(&i64); - ret = i64; - } else if (encoding >= ZIP_INT_IMM_MIN && encoding <= ZIP_INT_IMM_MAX) { - ret = (encoding & ZIP_INT_IMM_MASK)-1; - } else { - assert(NULL); - } - return ret; + int16_t i16; + int32_t i32; + int64_t i64, ret = 0; + if (encoding == ZIP_INT_8B) { + ret = ((int8_t *)p)[0]; + } else if (encoding == ZIP_INT_16B) { + memcpy(&i16, p, sizeof(i16)); + // memrev16ifbe(&i16); + ret = i16; + } else if (encoding == ZIP_INT_32B) { + memcpy(&i32, p, sizeof(i32)); + // memrev32ifbe(&i32); + ret = i32; + } else if (encoding == ZIP_INT_24B) { + i32 = 0; + memcpy(((uint8_t *)&i32) + 1, p, sizeof(i32) - sizeof(uint8_t)); + // memrev32ifbe(&i32); + ret = i32 >> 8; + } else if (encoding == ZIP_INT_64B) { + memcpy(&i64, p, sizeof(i64)); + // memrev64ifbe(&i64); + ret = i64; + } else if (encoding >= ZIP_INT_IMM_MIN && encoding <= ZIP_INT_IMM_MAX) { + ret = (encoding & ZIP_INT_IMM_MASK) - 1; + } else { + assert(NULL); + } + return ret; } /* Return a struct with all information about an entry. */ static zlentry zipEntry(unsigned char *p) { - zlentry e; + zlentry e; - ZIP_DECODE_PREVLEN(p, e.prevrawlensize, e.prevrawlen); - ZIP_DECODE_LENGTH(p + e.prevrawlensize, e.encoding, e.lensize, e.len); - e.headersize = e.prevrawlensize + e.lensize; - e.p = p; - return e; + ZIP_DECODE_PREVLEN(p, e.prevrawlensize, e.prevrawlen); + ZIP_DECODE_LENGTH(p + e.prevrawlensize, e.encoding, e.lensize, e.len); + e.headersize = e.prevrawlensize + e.lensize; + e.p = p; + return e; } /* Create a new empty ziplist. */ unsigned char *ziplistNew(void) { - unsigned int bytes = ZIPLIST_HEADER_SIZE+1; - unsigned char *zl = (unsigned char* )malloc(bytes); - ZIPLIST_BYTES(zl) = intrev32ifbe(bytes); - ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(ZIPLIST_HEADER_SIZE); - ZIPLIST_LENGTH(zl) = 0; - zl[bytes-1] = ZIP_END; - return zl; + unsigned int bytes = ZIPLIST_HEADER_SIZE + 1; + unsigned char *zl = (unsigned char *)malloc(bytes); + ZIPLIST_BYTES(zl) = intrev32ifbe(bytes); + ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(ZIPLIST_HEADER_SIZE); + ZIPLIST_LENGTH(zl) = 0; + zl[bytes - 1] = ZIP_END; + return zl; } /* Resize the ziplist. */ static unsigned char *ziplistResize(unsigned char *zl, unsigned int len) { - zl = (unsigned char* )realloc(zl,len); - ZIPLIST_BYTES(zl) = intrev32ifbe(len); - zl[len-1] = ZIP_END; - return zl; + zl = (unsigned char *)realloc(zl, len); + ZIPLIST_BYTES(zl) = intrev32ifbe(len); + zl[len - 1] = ZIP_END; + return zl; } /* When an entry is inserted, we need to set the prevlen field of the next @@ -466,246 +472,236 @@ static unsigned char *ziplistResize(unsigned char *zl, unsigned int len) { * The pointer "p" points to the first entry that does NOT need to be * updated, i.e. consecutive fields MAY need an update. */ static unsigned char *__ziplistCascadeUpdate(unsigned char *zl, unsigned char *p) { - size_t curlen = intrev32ifbe(ZIPLIST_BYTES(zl)), rawlen, rawlensize; - size_t offset, noffset, extra; - unsigned char *np; - zlentry cur, next; - - while (p[0] != ZIP_END) { - cur = zipEntry(p); - rawlen = cur.headersize + cur.len; - rawlensize = zipPrevEncodeLength(NULL,rawlen); - - /* Abort if there is no next entry. */ - if (p[rawlen] == ZIP_END) break; - next = zipEntry(p+rawlen); - - /* Abort when "prevlen" has not changed. */ - if (next.prevrawlen == rawlen) break; - - if (next.prevrawlensize < rawlensize) { - /* The "prevlen" field of "next" needs more bytes to hold - * the raw length of "cur". */ - offset = p-zl; - extra = rawlensize-next.prevrawlensize; - zl = ziplistResize(zl,curlen+extra); - p = zl+offset; - - /* Current pointer and offset for next element. */ - np = p+rawlen; - noffset = np-zl; - - /* Update tail offset when next element is not the tail element. */ - if ((zl+intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))) != np) { - ZIPLIST_TAIL_OFFSET(zl) = - intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))+extra); - } - - /* Move the tail to the back. */ - memmove(np+rawlensize, - np+next.prevrawlensize, - curlen-noffset-next.prevrawlensize-1); - zipPrevEncodeLength(np,rawlen); - - /* Advance the cursor */ - p += rawlen; - curlen += extra; - } else { - if (next.prevrawlensize > rawlensize) { - /* This would result in shrinking, which we want to avoid. - * So, set "rawlen" in the available bytes. */ - zipPrevEncodeLengthForceLarge(p+rawlen,rawlen); - } else { - zipPrevEncodeLength(p+rawlen,rawlen); - } - - /* Stop here, as the raw length of "next" has not changed. */ - break; - } + size_t curlen = intrev32ifbe(ZIPLIST_BYTES(zl)), rawlen, rawlensize; + size_t offset, noffset, extra; + unsigned char *np; + zlentry cur, next; + + while (p[0] != ZIP_END) { + cur = zipEntry(p); + rawlen = cur.headersize + cur.len; + rawlensize = zipPrevEncodeLength(NULL, rawlen); + + /* Abort if there is no next entry. */ + if (p[rawlen] == ZIP_END) break; + next = zipEntry(p + rawlen); + + /* Abort when "prevlen" has not changed. */ + if (next.prevrawlen == rawlen) break; + + if (next.prevrawlensize < rawlensize) { + /* The "prevlen" field of "next" needs more bytes to hold + * the raw length of "cur". */ + offset = p - zl; + extra = rawlensize - next.prevrawlensize; + zl = ziplistResize(zl, curlen + extra); + p = zl + offset; + + /* Current pointer and offset for next element. */ + np = p + rawlen; + noffset = np - zl; + + /* Update tail offset when next element is not the tail element. */ + if ((zl + intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))) != np) { + ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl)) + extra); + } + + /* Move the tail to the back. */ + memmove(np + rawlensize, np + next.prevrawlensize, curlen - noffset - next.prevrawlensize - 1); + zipPrevEncodeLength(np, rawlen); + + /* Advance the cursor */ + p += rawlen; + curlen += extra; + } else { + if (next.prevrawlensize > rawlensize) { + /* This would result in shrinking, which we want to avoid. + * So, set "rawlen" in the available bytes. */ + zipPrevEncodeLengthForceLarge(p + rawlen, rawlen); + } else { + zipPrevEncodeLength(p + rawlen, rawlen); + } + + /* Stop here, as the raw length of "next" has not changed. */ + break; } - return zl; + } + return zl; } /* Delete "num" entries, starting at "p". Returns pointer to the ziplist. */ static unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, unsigned int num) { - unsigned int i, totlen, deleted = 0; - size_t offset; - int nextdiff = 0; - zlentry first, tail; - - first = zipEntry(p); - for (i = 0; p[0] != ZIP_END && i < num; i++) { - p += zipRawEntryLength(p); - deleted++; - } + unsigned int i, totlen, deleted = 0; + size_t offset; + int nextdiff = 0; + zlentry first, tail; - totlen = p-first.p; - if (totlen > 0) { - if (p[0] != ZIP_END) { - /* Storing `prevrawlen` in this entry may increase or decrease the - * number of bytes required compare to the current `prevrawlen`. - * There always is room to store this, because it was previously - * stored by an entry that is now being deleted. */ - nextdiff = zipPrevLenByteDiff(p,first.prevrawlen); - p -= nextdiff; - zipPrevEncodeLength(p,first.prevrawlen); - - /* Update offset for tail */ - ZIPLIST_TAIL_OFFSET(zl) = - intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))-totlen); - - /* When the tail contains more than one entry, we need to take - * "nextdiff" in account as well. Otherwise, a change in the - * size of prevlen doesn't have an effect on the *tail* offset. */ - tail = zipEntry(p); - if (p[tail.headersize+tail.len] != ZIP_END) { - ZIPLIST_TAIL_OFFSET(zl) = - intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))+nextdiff); - } - - /* Move tail to the front of the ziplist */ - memmove(first.p,p, - intrev32ifbe(ZIPLIST_BYTES(zl))-(p-zl)-1); - } else { - /* The entire tail was deleted. No need to move memory. */ - ZIPLIST_TAIL_OFFSET(zl) = - intrev32ifbe((first.p-zl)-first.prevrawlen); - } - - /* Resize and update length */ - offset = first.p-zl; - zl = ziplistResize(zl, intrev32ifbe(ZIPLIST_BYTES(zl))-totlen+nextdiff); - ZIPLIST_INCR_LENGTH(zl,-deleted); - p = zl+offset; - - /* When nextdiff != 0, the raw length of the next entry has changed, so - * we need to cascade the update throughout the ziplist */ - if (nextdiff != 0) - zl = __ziplistCascadeUpdate(zl,p); - } - return zl; -} + first = zipEntry(p); + for (i = 0; p[0] != ZIP_END && i < num; i++) { + p += zipRawEntryLength(p); + deleted++; + } -/* Insert item at "p". */ -static unsigned char *__ziplistInsert(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen) { - size_t curlen = intrev32ifbe(ZIPLIST_BYTES(zl)), reqlen, prevlen = 0; - size_t offset; - int nextdiff = 0; - unsigned char encoding = 0; - long long value = 123456789; /* initialized to avoid warning. Using a value - that is easy to see if for some reason - we use it uninitialized. */ - zlentry entry, tail; - - /* Find out prevlen for the entry that is inserted. */ + totlen = p - first.p; + if (totlen > 0) { if (p[0] != ZIP_END) { - entry = zipEntry(p); - prevlen = entry.prevrawlen; + /* Storing `prevrawlen` in this entry may increase or decrease the + * number of bytes required compare to the current `prevrawlen`. + * There always is room to store this, because it was previously + * stored by an entry that is now being deleted. */ + nextdiff = zipPrevLenByteDiff(p, first.prevrawlen); + p -= nextdiff; + zipPrevEncodeLength(p, first.prevrawlen); + + /* Update offset for tail */ + ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl)) - totlen); + + /* When the tail contains more than one entry, we need to take + * "nextdiff" in account as well. Otherwise, a change in the + * size of prevlen doesn't have an effect on the *tail* offset. */ + tail = zipEntry(p); + if (p[tail.headersize + tail.len] != ZIP_END) { + ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl)) + nextdiff); + } + + /* Move tail to the front of the ziplist */ + memmove(first.p, p, intrev32ifbe(ZIPLIST_BYTES(zl)) - (p - zl) - 1); } else { - unsigned char *ptail = ZIPLIST_ENTRY_TAIL(zl); - if (ptail[0] != ZIP_END) { - prevlen = zipRawEntryLength(ptail); - } + /* The entire tail was deleted. No need to move memory. */ + ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe((first.p - zl) - first.prevrawlen); } - /* See if the entry can be encoded */ - if (zipTryEncoding(s,slen,&value,&encoding)) { - /* 'encoding' is set to the appropriate integer encoding */ - reqlen = zipIntSize(encoding); - } else { - /* 'encoding' is untouched, however zipEncodeLength will use the - * string length to figure out how to encode it. */ - reqlen = slen; - } - /* We need space for both the length of the previous entry and - * the length of the payload. */ - reqlen += zipPrevEncodeLength(NULL,prevlen); - reqlen += zipEncodeLength(NULL,encoding,slen); - - /* When the insert position is not equal to the tail, we need to - * make sure that the next entry can hold this entry's length in - * its prevlen field. */ - nextdiff = (p[0] != ZIP_END) ? zipPrevLenByteDiff(p,reqlen) : 0; - - /* Store offset because a realloc may change the address of zl. */ - offset = p-zl; - zl = ziplistResize(zl,curlen+reqlen+nextdiff); - p = zl+offset; - - /* Apply memory move when necessary and update tail offset. */ - if (p[0] != ZIP_END) { - /* Subtract one because of the ZIP_END bytes */ - memmove(p+reqlen,p-nextdiff,curlen-offset-1+nextdiff); - - /* Encode this entry's raw length in the next entry. */ - zipPrevEncodeLength(p+reqlen,reqlen); - - /* Update offset for tail */ - ZIPLIST_TAIL_OFFSET(zl) = - intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))+reqlen); - - /* When the tail contains more than one entry, we need to take - * "nextdiff" in account as well. Otherwise, a change in the - * size of prevlen doesn't have an effect on the *tail* offset. */ - tail = zipEntry(p+reqlen); - if (p[reqlen+tail.headersize+tail.len] != ZIP_END) { - ZIPLIST_TAIL_OFFSET(zl) = - intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))+nextdiff); - } - } else { - /* This element will be the new tail. */ - ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(p-zl); - } + /* Resize and update length */ + offset = first.p - zl; + zl = ziplistResize(zl, intrev32ifbe(ZIPLIST_BYTES(zl)) - totlen + nextdiff); + ZIPLIST_INCR_LENGTH(zl, -deleted); + p = zl + offset; /* When nextdiff != 0, the raw length of the next entry has changed, so * we need to cascade the update throughout the ziplist */ - if (nextdiff != 0) { - offset = p-zl; - zl = __ziplistCascadeUpdate(zl,p+reqlen); - p = zl+offset; - } + if (nextdiff != 0) zl = __ziplistCascadeUpdate(zl, p); + } + return zl; +} - /* Write the entry */ - p += zipPrevEncodeLength(p,prevlen); - p += zipEncodeLength(p,encoding,slen); - if (ZIP_IS_STR(encoding)) { - memcpy(p,s,slen); - } else { - zipSaveInteger(p,value,encoding); +/* Insert item at "p". */ +static unsigned char *__ziplistInsert(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen) { + size_t curlen = intrev32ifbe(ZIPLIST_BYTES(zl)), reqlen, prevlen = 0; + size_t offset; + int nextdiff = 0; + unsigned char encoding = 0; + long long value = 123456789; /* initialized to avoid warning. Using a value + that is easy to see if for some reason + we use it uninitialized. */ + zlentry entry, tail; + + /* Find out prevlen for the entry that is inserted. */ + if (p[0] != ZIP_END) { + entry = zipEntry(p); + prevlen = entry.prevrawlen; + } else { + unsigned char *ptail = ZIPLIST_ENTRY_TAIL(zl); + if (ptail[0] != ZIP_END) { + prevlen = zipRawEntryLength(ptail); } - ZIPLIST_INCR_LENGTH(zl,1); - return zl; + } + + /* See if the entry can be encoded */ + if (zipTryEncoding(s, slen, &value, &encoding)) { + /* 'encoding' is set to the appropriate integer encoding */ + reqlen = zipIntSize(encoding); + } else { + /* 'encoding' is untouched, however zipEncodeLength will use the + * string length to figure out how to encode it. */ + reqlen = slen; + } + /* We need space for both the length of the previous entry and + * the length of the payload. */ + reqlen += zipPrevEncodeLength(NULL, prevlen); + reqlen += zipEncodeLength(NULL, encoding, slen); + + /* When the insert position is not equal to the tail, we need to + * make sure that the next entry can hold this entry's length in + * its prevlen field. */ + nextdiff = (p[0] != ZIP_END) ? zipPrevLenByteDiff(p, reqlen) : 0; + + /* Store offset because a realloc may change the address of zl. */ + offset = p - zl; + zl = ziplistResize(zl, curlen + reqlen + nextdiff); + p = zl + offset; + + /* Apply memory move when necessary and update tail offset. */ + if (p[0] != ZIP_END) { + /* Subtract one because of the ZIP_END bytes */ + memmove(p + reqlen, p - nextdiff, curlen - offset - 1 + nextdiff); + + /* Encode this entry's raw length in the next entry. */ + zipPrevEncodeLength(p + reqlen, reqlen); + + /* Update offset for tail */ + ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl)) + reqlen); + + /* When the tail contains more than one entry, we need to take + * "nextdiff" in account as well. Otherwise, a change in the + * size of prevlen doesn't have an effect on the *tail* offset. */ + tail = zipEntry(p + reqlen); + if (p[reqlen + tail.headersize + tail.len] != ZIP_END) { + ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl)) + nextdiff); + } + } else { + /* This element will be the new tail. */ + ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(p - zl); + } + + /* When nextdiff != 0, the raw length of the next entry has changed, so + * we need to cascade the update throughout the ziplist */ + if (nextdiff != 0) { + offset = p - zl; + zl = __ziplistCascadeUpdate(zl, p + reqlen); + p = zl + offset; + } + + /* Write the entry */ + p += zipPrevEncodeLength(p, prevlen); + p += zipEncodeLength(p, encoding, slen); + if (ZIP_IS_STR(encoding)) { + memcpy(p, s, slen); + } else { + zipSaveInteger(p, value, encoding); + } + ZIPLIST_INCR_LENGTH(zl, 1); + return zl; } unsigned char *ziplistPush(unsigned char *zl, unsigned char *s, unsigned int slen, int where) { - unsigned char *p; - p = (where == ZIPLIST_HEAD) ? ZIPLIST_ENTRY_HEAD(zl) : ZIPLIST_ENTRY_END(zl); - return __ziplistInsert(zl,p,s,slen); + unsigned char *p; + p = (where == ZIPLIST_HEAD) ? ZIPLIST_ENTRY_HEAD(zl) : ZIPLIST_ENTRY_END(zl); + return __ziplistInsert(zl, p, s, slen); } /* Returns an offset to use for iterating with ziplistNext. When the given * index is negative, the list is traversed back to front. When the list * doesn't contain an element at the provided index, NULL is returned. */ unsigned char *ziplistIndex(unsigned char *zl, int index) { - unsigned char *p; - zlentry entry; - if (index < 0) { - index = (-index)-1; - p = ZIPLIST_ENTRY_TAIL(zl); - if (p[0] != ZIP_END) { - entry = zipEntry(p); - while (entry.prevrawlen > 0 && index--) { - p -= entry.prevrawlen; - entry = zipEntry(p); - } - } - } else { - p = ZIPLIST_ENTRY_HEAD(zl); - while (p[0] != ZIP_END && index--) { - p += zipRawEntryLength(p); - } + unsigned char *p; + zlentry entry; + if (index < 0) { + index = (-index) - 1; + p = ZIPLIST_ENTRY_TAIL(zl); + if (p[0] != ZIP_END) { + entry = zipEntry(p); + while (entry.prevrawlen > 0 && index--) { + p -= entry.prevrawlen; + entry = zipEntry(p); + } } - return (p[0] == ZIP_END || index > 0) ? NULL : p; + } else { + p = ZIPLIST_ENTRY_HEAD(zl); + while (p[0] != ZIP_END && index--) { + p += zipRawEntryLength(p); + } + } + return (p[0] == ZIP_END || index > 0) ? NULL : p; } /* Return pointer to next entry in ziplist. @@ -715,40 +711,40 @@ unsigned char *ziplistIndex(unsigned char *zl, int index) { * * The element after 'p' is returned, otherwise NULL if we are at the end. */ unsigned char *ziplistNext(unsigned char *zl, unsigned char *p) { - ((void) zl); + ((void)zl); - /* "p" could be equal to ZIP_END, caused by ziplistDelete, - * and we should return NULL. Otherwise, we should return NULL - * when the *next* element is ZIP_END (there is no next entry). */ - if (p[0] == ZIP_END) { - return NULL; - } + /* "p" could be equal to ZIP_END, caused by ziplistDelete, + * and we should return NULL. Otherwise, we should return NULL + * when the *next* element is ZIP_END (there is no next entry). */ + if (p[0] == ZIP_END) { + return NULL; + } - p += zipRawEntryLength(p); - if (p[0] == ZIP_END) { - return NULL; - } + p += zipRawEntryLength(p); + if (p[0] == ZIP_END) { + return NULL; + } - return p; + return p; } /* Return pointer to previous entry in ziplist. */ unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p) { - zlentry entry; - - /* Iterating backwards from ZIP_END should return the tail. When "p" is - * equal to the first element of the list, we're already at the head, - * and should return NULL. */ - if (p[0] == ZIP_END) { - p = ZIPLIST_ENTRY_TAIL(zl); - return (p[0] == ZIP_END) ? NULL : p; - } else if (p == ZIPLIST_ENTRY_HEAD(zl)) { - return NULL; - } else { - entry = zipEntry(p); - assert(entry.prevrawlen > 0); - return p-entry.prevrawlen; - } + zlentry entry; + + /* Iterating backwards from ZIP_END should return the tail. When "p" is + * equal to the first element of the list, we're already at the head, + * and should return NULL. */ + if (p[0] == ZIP_END) { + p = ZIPLIST_ENTRY_TAIL(zl); + return (p[0] == ZIP_END) ? NULL : p; + } else if (p == ZIPLIST_ENTRY_HEAD(zl)) { + return NULL; + } else { + entry = zipEntry(p); + assert(entry.prevrawlen > 0); + return p - entry.prevrawlen; + } } /* Get entry pointed to by 'p' and store in either 'e' or 'v' depending @@ -756,791 +752,781 @@ unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p) { * to find out whether the string pointer or the integer value was set. * Return 0 if 'p' points to the end of the ziplist, 1 otherwise. */ unsigned int ziplistGet(unsigned char *p, unsigned char **sstr, unsigned int *slen, long long *sval) { - zlentry entry; - if (p == NULL || p[0] == ZIP_END) return 0; - if (sstr) *sstr = NULL; - - entry = zipEntry(p); - if (ZIP_IS_STR(entry.encoding)) { - if (sstr) { - *slen = entry.len; - *sstr = p+entry.headersize; - } - } else { - if (sval) { - *sval = zipLoadInteger(p+entry.headersize,entry.encoding); - } + zlentry entry; + if (p == NULL || p[0] == ZIP_END) return 0; + if (sstr) *sstr = NULL; + + entry = zipEntry(p); + if (ZIP_IS_STR(entry.encoding)) { + if (sstr) { + *slen = entry.len; + *sstr = p + entry.headersize; } - return 1; + } else { + if (sval) { + *sval = zipLoadInteger(p + entry.headersize, entry.encoding); + } + } + return 1; } /* Insert an entry at "p". */ unsigned char *ziplistInsert(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen) { - return __ziplistInsert(zl,p,s,slen); + return __ziplistInsert(zl, p, s, slen); } /* Delete a single entry from the ziplist, pointed to by *p. * Also update *p in place, to be able to iterate over the * ziplist, while deleting entries. */ unsigned char *ziplistDelete(unsigned char *zl, unsigned char **p) { - size_t offset = *p-zl; - zl = __ziplistDelete(zl,*p,1); - - /* Store pointer to current element in p, because ziplistDelete will - * do a realloc which might result in a different "zl"-pointer. - * When the delete direction is back to front, we might delete the last - * entry and end up with "p" pointing to ZIP_END, so check this. */ - *p = zl+offset; - return zl; + size_t offset = *p - zl; + zl = __ziplistDelete(zl, *p, 1); + + /* Store pointer to current element in p, because ziplistDelete will + * do a realloc which might result in a different "zl"-pointer. + * When the delete direction is back to front, we might delete the last + * entry and end up with "p" pointing to ZIP_END, so check this. */ + *p = zl + offset; + return zl; } /* Delete a range of entries from the ziplist. */ unsigned char *ziplistDeleteRange(unsigned char *zl, unsigned int index, unsigned int num) { - unsigned char *p = ziplistIndex(zl,index); - return (p == NULL) ? zl : __ziplistDelete(zl,p,num); + unsigned char *p = ziplistIndex(zl, index); + return (p == NULL) ? zl : __ziplistDelete(zl, p, num); } /* Compare entry pointer to by 'p' with 'entry'. Return 1 if equal. */ unsigned int ziplistCompare(unsigned char *p, unsigned char *sstr, unsigned int slen) { - zlentry entry; - unsigned char sencoding; - long long zval, sval; - if (p[0] == ZIP_END) return 0; - - entry = zipEntry(p); - if (ZIP_IS_STR(entry.encoding)) { - /* Raw compare */ - if (entry.len == slen) { - return memcmp(p+entry.headersize,sstr,slen) == 0; - } else { - return 0; - } + zlentry entry; + unsigned char sencoding; + long long zval, sval; + if (p[0] == ZIP_END) return 0; + + entry = zipEntry(p); + if (ZIP_IS_STR(entry.encoding)) { + /* Raw compare */ + if (entry.len == slen) { + return memcmp(p + entry.headersize, sstr, slen) == 0; } else { - /* Try to compare encoded values. Don't compare encoding because - * different implementations may encoded integers differently. */ - if (zipTryEncoding(sstr,slen,&sval,&sencoding)) { - zval = zipLoadInteger(p+entry.headersize,entry.encoding); - return zval == sval; - } + return 0; + } + } else { + /* Try to compare encoded values. Don't compare encoding because + * different implementations may encoded integers differently. */ + if (zipTryEncoding(sstr, slen, &sval, &sencoding)) { + zval = zipLoadInteger(p + entry.headersize, entry.encoding); + return zval == sval; } - return 0; + } + return 0; } /* Find pointer to the entry equal to the specified entry. Skip 'skip' entries * between every comparison. Returns NULL when the field could not be found. */ unsigned char *ziplistFind(unsigned char *p, unsigned char *vstr, unsigned int vlen, unsigned int skip) { - int skipcnt = 0; - unsigned char vencoding = 0; - long long vll = 0; - - while (p[0] != ZIP_END) { - unsigned int prevlensize, encoding, lensize, len; - unsigned char *q; - - ZIP_DECODE_PREVLENSIZE(p, prevlensize); - ZIP_DECODE_LENGTH(p + prevlensize, encoding, lensize, len); - q = p + prevlensize + lensize; - - if (skipcnt == 0) { - /* Compare current entry with specified entry */ - if (ZIP_IS_STR(encoding)) { - if (len == vlen && memcmp(q, vstr, vlen) == 0) { - return p; - } - } else { - /* Find out if the searched field can be encoded. Note that - * we do it only the first time, once done vencoding is set - * to non-zero and vll is set to the integer value. */ - if (vencoding == 0) { - if (!zipTryEncoding(vstr, vlen, &vll, &vencoding)) { - /* If the entry can't be encoded we set it to - * UCHAR_MAX so that we don't retry again the next - * time. */ - vencoding = UCHAR_MAX; - } - /* Must be non-zero by now */ - assert(vencoding); - } - - /* Compare current entry with specified entry, do it only - * if vencoding != UCHAR_MAX because if there is no encoding - * possible for the field it can't be a valid integer. */ - if (vencoding != UCHAR_MAX) { - long long ll = zipLoadInteger(q, encoding); - if (ll == vll) { - return p; - } - } - } - - /* Reset skip count */ - skipcnt = skip; - } else { - /* Skip entry */ - skipcnt--; + int skipcnt = 0; + unsigned char vencoding = 0; + long long vll = 0; + + while (p[0] != ZIP_END) { + unsigned int prevlensize, encoding, lensize, len; + unsigned char *q; + + ZIP_DECODE_PREVLENSIZE(p, prevlensize); + ZIP_DECODE_LENGTH(p + prevlensize, encoding, lensize, len); + q = p + prevlensize + lensize; + + if (skipcnt == 0) { + /* Compare current entry with specified entry */ + if (ZIP_IS_STR(encoding)) { + if (len == vlen && memcmp(q, vstr, vlen) == 0) { + return p; + } + } else { + /* Find out if the searched field can be encoded. Note that + * we do it only the first time, once done vencoding is set + * to non-zero and vll is set to the integer value. */ + if (vencoding == 0) { + if (!zipTryEncoding(vstr, vlen, &vll, &vencoding)) { + /* If the entry can't be encoded we set it to + * UCHAR_MAX so that we don't retry again the next + * time. */ + vencoding = UCHAR_MAX; + } + /* Must be non-zero by now */ + assert(vencoding); } - /* Move to next entry */ - p = q + len; + /* Compare current entry with specified entry, do it only + * if vencoding != UCHAR_MAX because if there is no encoding + * possible for the field it can't be a valid integer. */ + if (vencoding != UCHAR_MAX) { + long long ll = zipLoadInteger(q, encoding); + if (ll == vll) { + return p; + } + } + } + + /* Reset skip count */ + skipcnt = skip; + } else { + /* Skip entry */ + skipcnt--; } - return NULL; + /* Move to next entry */ + p = q + len; + } + + return NULL; } /* Return length of ziplist. */ unsigned int ziplistLen(unsigned char *zl) { - unsigned int len = 0; - if (intrev16ifbe(ZIPLIST_LENGTH(zl)) < UINT16_MAX) { - len = intrev16ifbe(ZIPLIST_LENGTH(zl)); - } else { - unsigned char *p = zl+ZIPLIST_HEADER_SIZE; - while (*p != ZIP_END) { - p += zipRawEntryLength(p); - len++; - } - - /* Re-store length if small enough */ - if (len < UINT16_MAX) ZIPLIST_LENGTH(zl) = intrev16ifbe(len); + unsigned int len = 0; + if (intrev16ifbe(ZIPLIST_LENGTH(zl)) < UINT16_MAX) { + len = intrev16ifbe(ZIPLIST_LENGTH(zl)); + } else { + unsigned char *p = zl + ZIPLIST_HEADER_SIZE; + while (*p != ZIP_END) { + p += zipRawEntryLength(p); + len++; } - return len; + + /* Re-store length if small enough */ + if (len < UINT16_MAX) ZIPLIST_LENGTH(zl) = intrev16ifbe(len); + } + return len; } /* Return ziplist blob size in bytes. */ -size_t ziplistBlobLen(unsigned char *zl) { - return intrev32ifbe(ZIPLIST_BYTES(zl)); -} +size_t ziplistBlobLen(unsigned char *zl) { return intrev32ifbe(ZIPLIST_BYTES(zl)); } void ziplistRepr(unsigned char *zl) { - unsigned char *p; - int index = 0; - zlentry entry; - + unsigned char *p; + int index = 0; + zlentry entry; + + printf( + "{total bytes %d} " + "{length %u}\n" + "{tail offset %u}\n", + intrev32ifbe(ZIPLIST_BYTES(zl)), intrev16ifbe(ZIPLIST_LENGTH(zl)), intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))); + p = ZIPLIST_ENTRY_HEAD(zl); + while (*p != ZIP_END) { + entry = zipEntry(p); printf( - "{total bytes %d} " - "{length %u}\n" - "{tail offset %u}\n", - intrev32ifbe(ZIPLIST_BYTES(zl)), - intrev16ifbe(ZIPLIST_LENGTH(zl)), - intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))); - p = ZIPLIST_ENTRY_HEAD(zl); - while(*p != ZIP_END) { - entry = zipEntry(p); - printf( - "{" - "addr 0x%08lx, " - "index %2d, " - "offset %5ld, " - "rl: %5u, " - "hs %2u, " - "pl: %5u, " - "pls: %2u, " - "payload %5u" - "} ", - (long unsigned)p, - index, - (unsigned long) (p-zl), - entry.headersize+entry.len, - entry.headersize, - entry.prevrawlen, - entry.prevrawlensize, - entry.len); - p += entry.headersize; - if (ZIP_IS_STR(entry.encoding)) { - if (entry.len > 40) { - if (fwrite(p,40,1,stdout) == 0) perror("fwrite"); - printf("..."); - } else { - if (entry.len && - fwrite(p,entry.len,1,stdout) == 0) perror("fwrite"); - } - } else { - printf("%lld", (long long) zipLoadInteger(p,entry.encoding)); - } - printf("\n"); - p += entry.len; - index++; + "{" + "addr 0x%08lx, " + "index %2d, " + "offset %5ld, " + "rl: %5u, " + "hs %2u, " + "pl: %5u, " + "pls: %2u, " + "payload %5u" + "} ", + (long unsigned)p, index, (unsigned long)(p - zl), entry.headersize + entry.len, entry.headersize, + entry.prevrawlen, entry.prevrawlensize, entry.len); + p += entry.headersize; + if (ZIP_IS_STR(entry.encoding)) { + if (entry.len > 40) { + if (fwrite(p, 40, 1, stdout) == 0) perror("fwrite"); + printf("..."); + } else { + if (entry.len && fwrite(p, entry.len, 1, stdout) == 0) perror("fwrite"); + } + } else { + printf("%lld", (long long)zipLoadInteger(p, entry.encoding)); } - printf("{end}\n\n"); + printf("\n"); + p += entry.len; + index++; + } + printf("{end}\n\n"); } #ifdef ZIPLIST_TEST_MAIN -#include -#include "adlist.h" -#include "sds.h" +# include +# include "adlist.h" +# include "sds.h" -#define debug(f, ...) { if (DEBUG) printf(f, __VA_ARGS__); } +# define debug(f, ...) \ + { \ + if (DEBUG) printf(f, __VA_ARGS__); \ + } unsigned char *createList() { - unsigned char *zl = ziplistNew(); - zl = ziplistPush(zl, (unsigned char*)"foo", 3, ZIPLIST_TAIL); - zl = ziplistPush(zl, (unsigned char*)"quux", 4, ZIPLIST_TAIL); - zl = ziplistPush(zl, (unsigned char*)"hello", 5, ZIPLIST_HEAD); - zl = ziplistPush(zl, (unsigned char*)"1024", 4, ZIPLIST_TAIL); - return zl; + unsigned char *zl = ziplistNew(); + zl = ziplistPush(zl, (unsigned char *)"foo", 3, ZIPLIST_TAIL); + zl = ziplistPush(zl, (unsigned char *)"quux", 4, ZIPLIST_TAIL); + zl = ziplistPush(zl, (unsigned char *)"hello", 5, ZIPLIST_HEAD); + zl = ziplistPush(zl, (unsigned char *)"1024", 4, ZIPLIST_TAIL); + return zl; } unsigned char *createIntList() { - unsigned char *zl = ziplistNew(); - char buf[32]; - - sprintf(buf, "100"); - zl = ziplistPush(zl, (unsigned char*)buf, strlen(buf), ZIPLIST_TAIL); - sprintf(buf, "128000"); - zl = ziplistPush(zl, (unsigned char*)buf, strlen(buf), ZIPLIST_TAIL); - sprintf(buf, "-100"); - zl = ziplistPush(zl, (unsigned char*)buf, strlen(buf), ZIPLIST_HEAD); - sprintf(buf, "4294967296"); - zl = ziplistPush(zl, (unsigned char*)buf, strlen(buf), ZIPLIST_HEAD); - sprintf(buf, "non integer"); - zl = ziplistPush(zl, (unsigned char*)buf, strlen(buf), ZIPLIST_TAIL); - sprintf(buf, "much much longer non integer"); - zl = ziplistPush(zl, (unsigned char*)buf, strlen(buf), ZIPLIST_TAIL); - return zl; + unsigned char *zl = ziplistNew(); + char buf[32]; + + sprintf(buf, "100"); + zl = ziplistPush(zl, (unsigned char *)buf, strlen(buf), ZIPLIST_TAIL); + sprintf(buf, "128000"); + zl = ziplistPush(zl, (unsigned char *)buf, strlen(buf), ZIPLIST_TAIL); + sprintf(buf, "-100"); + zl = ziplistPush(zl, (unsigned char *)buf, strlen(buf), ZIPLIST_HEAD); + sprintf(buf, "4294967296"); + zl = ziplistPush(zl, (unsigned char *)buf, strlen(buf), ZIPLIST_HEAD); + sprintf(buf, "non integer"); + zl = ziplistPush(zl, (unsigned char *)buf, strlen(buf), ZIPLIST_TAIL); + sprintf(buf, "much much longer non integer"); + zl = ziplistPush(zl, (unsigned char *)buf, strlen(buf), ZIPLIST_TAIL); + return zl; } long long usec(void) { - struct timeval tv; - gettimeofday(&tv,NULL); - return (((long long)tv.tv_sec)*1000000)+tv.tv_usec; + struct timeval tv; + gettimeofday(&tv, NULL); + return (((long long)tv.tv_sec) * 1000000) + tv.tv_usec; } void stress(int pos, int num, int maxsize, int dnum) { - int i,j,k; - unsigned char *zl; - char posstr[2][5] = { "HEAD", "TAIL" }; - long long start; - for (i = 0; i < maxsize; i+=dnum) { - zl = ziplistNew(); - for (j = 0; j < i; j++) { - zl = ziplistPush(zl,(unsigned char*)"quux",4,ZIPLIST_TAIL); - } + int i, j, k; + unsigned char *zl; + char posstr[2][5] = {"HEAD", "TAIL"}; + long long start; + for (i = 0; i < maxsize; i += dnum) { + zl = ziplistNew(); + for (j = 0; j < i; j++) { + zl = ziplistPush(zl, (unsigned char *)"quux", 4, ZIPLIST_TAIL); + } - /* Do num times a push+pop from pos */ - start = usec(); - for (k = 0; k < num; k++) { - zl = ziplistPush(zl,(unsigned char*)"quux",4,pos); - zl = ziplistDeleteRange(zl,0,1); - } - printf("List size: %8d, bytes: %8d, %dx push+pop (%s): %6lld usec\n", - i,intrev32ifbe(ZIPLIST_BYTES(zl)),num,posstr[pos],usec()-start); - zfree(zl); + /* Do num times a push+pop from pos */ + start = usec(); + for (k = 0; k < num; k++) { + zl = ziplistPush(zl, (unsigned char *)"quux", 4, pos); + zl = ziplistDeleteRange(zl, 0, 1); } + printf("List size: %8d, bytes: %8d, %dx push+pop (%s): %6lld usec\n", i, intrev32ifbe(ZIPLIST_BYTES(zl)), num, + posstr[pos], usec() - start); + zfree(zl); + } } void pop(unsigned char *zl, int where) { - unsigned char *p, *vstr; - unsigned int vlen; - long long vlong; - - p = ziplistIndex(zl,where == ZIPLIST_HEAD ? 0 : -1); - if (ziplistGet(p,&vstr,&vlen,&vlong)) { - if (where == ZIPLIST_HEAD) - printf("Pop head: "); - else - printf("Pop tail: "); - - if (vstr) - if (vlen && fwrite(vstr,vlen,1,stdout) == 0) perror("fwrite"); - else - printf("%lld", vlong); - - printf("\n"); - ziplistDeleteRange(zl,-1,1); - } else { - printf("ERROR: Could not pop\n"); - exit(1); - } + unsigned char *p, *vstr; + unsigned int vlen; + long long vlong; + + p = ziplistIndex(zl, where == ZIPLIST_HEAD ? 0 : -1); + if (ziplistGet(p, &vstr, &vlen, &vlong)) { + if (where == ZIPLIST_HEAD) + printf("Pop head: "); + else + printf("Pop tail: "); + + if (vstr) + if (vlen && fwrite(vstr, vlen, 1, stdout) == 0) + perror("fwrite"); + else + printf("%lld", vlong); + + printf("\n"); + ziplistDeleteRange(zl, -1, 1); + } else { + printf("ERROR: Could not pop\n"); + exit(1); + } } int randstring(char *target, unsigned int min, unsigned int max) { - int p, len = min+rand()%(max-min+1); - int minval, maxval; - switch(rand() % 3) { + int p, len = min + rand() % (max - min + 1); + int minval, maxval; + switch (rand() % 3) { case 0: - minval = 0; - maxval = 255; - break; + minval = 0; + maxval = 255; + break; case 1: - minval = 48; - maxval = 122; - break; + minval = 48; + maxval = 122; + break; case 2: - minval = 48; - maxval = 52; - break; + minval = 48; + maxval = 52; + break; default: - assert(NULL); - } + assert(NULL); + } - while(p < len) - target[p++] = minval+rand()%(maxval-minval+1); - return len; + while (p < len) target[p++] = minval + rand() % (maxval - minval + 1); + return len; } void verify(unsigned char *zl, zlentry *e) { - int i; - int len = ziplistLen(zl); - zlentry _e; + int i; + int len = ziplistLen(zl); + zlentry _e; - for (i = 0; i < len; i++) { - memset(&e[i], 0, sizeof(zlentry)); - e[i] = zipEntry(ziplistIndex(zl, i)); + for (i = 0; i < len; i++) { + memset(&e[i], 0, sizeof(zlentry)); + e[i] = zipEntry(ziplistIndex(zl, i)); - memset(&_e, 0, sizeof(zlentry)); - _e = zipEntry(ziplistIndex(zl, -len+i)); + memset(&_e, 0, sizeof(zlentry)); + _e = zipEntry(ziplistIndex(zl, -len + i)); - assert(memcmp(&e[i], &_e, sizeof(zlentry)) == 0); - } + assert(memcmp(&e[i], &_e, sizeof(zlentry)) == 0); + } } int main(int argc, char **argv) { - unsigned char *zl, *p; - unsigned char *entry; - unsigned int elen; - long long value; + unsigned char *zl, *p; + unsigned char *entry; + unsigned int elen; + long long value; - /* If an argument is given, use it as the random seed. */ - if (argc == 2) - srand(atoi(argv[1])); + /* If an argument is given, use it as the random seed. */ + if (argc == 2) srand(atoi(argv[1])); - zl = createIntList(); - ziplistRepr(zl); + zl = createIntList(); + ziplistRepr(zl); - zl = createList(); - ziplistRepr(zl); + zl = createList(); + ziplistRepr(zl); - pop(zl,ZIPLIST_TAIL); - ziplistRepr(zl); + pop(zl, ZIPLIST_TAIL); + ziplistRepr(zl); - pop(zl,ZIPLIST_HEAD); - ziplistRepr(zl); + pop(zl, ZIPLIST_HEAD); + ziplistRepr(zl); - pop(zl,ZIPLIST_TAIL); - ziplistRepr(zl); + pop(zl, ZIPLIST_TAIL); + ziplistRepr(zl); - pop(zl,ZIPLIST_TAIL); - ziplistRepr(zl); + pop(zl, ZIPLIST_TAIL); + ziplistRepr(zl); - printf("Get element at index 3:\n"); - { - zl = createList(); - p = ziplistIndex(zl, 3); - if (!ziplistGet(p, &entry, &elen, &value)) { - printf("ERROR: Could not access index 3\n"); - return 1; - } - if (entry) { - if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite"); - printf("\n"); - } else { - printf("%lld\n", value); - } - printf("\n"); + printf("Get element at index 3:\n"); + { + zl = createList(); + p = ziplistIndex(zl, 3); + if (!ziplistGet(p, &entry, &elen, &value)) { + printf("ERROR: Could not access index 3\n"); + return 1; } - - printf("Get element at index 4 (out of range):\n"); - { - zl = createList(); - p = ziplistIndex(zl, 4); - if (p == NULL) { - printf("No entry\n"); - } else { - printf("ERROR: Out of range index should return NULL, returned offset: %ld\n", p-zl); - return 1; - } - printf("\n"); + if (entry) { + if (elen && fwrite(entry, elen, 1, stdout) == 0) perror("fwrite"); + printf("\n"); + } else { + printf("%lld\n", value); } + printf("\n"); + } - printf("Get element at index -1 (last element):\n"); - { - zl = createList(); - p = ziplistIndex(zl, -1); - if (!ziplistGet(p, &entry, &elen, &value)) { - printf("ERROR: Could not access index -1\n"); - return 1; - } - if (entry) { - if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite"); - printf("\n"); - } else { - printf("%lld\n", value); - } - printf("\n"); + printf("Get element at index 4 (out of range):\n"); + { + zl = createList(); + p = ziplistIndex(zl, 4); + if (p == NULL) { + printf("No entry\n"); + } else { + printf("ERROR: Out of range index should return NULL, returned offset: %ld\n", p - zl); + return 1; } + printf("\n"); + } - printf("Get element at index -4 (first element):\n"); - { - zl = createList(); - p = ziplistIndex(zl, -4); - if (!ziplistGet(p, &entry, &elen, &value)) { - printf("ERROR: Could not access index -4\n"); - return 1; - } - if (entry) { - if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite"); - printf("\n"); - } else { - printf("%lld\n", value); - } - printf("\n"); + printf("Get element at index -1 (last element):\n"); + { + zl = createList(); + p = ziplistIndex(zl, -1); + if (!ziplistGet(p, &entry, &elen, &value)) { + printf("ERROR: Could not access index -1\n"); + return 1; } - - printf("Get element at index -5 (reverse out of range):\n"); - { - zl = createList(); - p = ziplistIndex(zl, -5); - if (p == NULL) { - printf("No entry\n"); - } else { - printf("ERROR: Out of range index should return NULL, returned offset: %ld\n", p-zl); - return 1; - } - printf("\n"); + if (entry) { + if (elen && fwrite(entry, elen, 1, stdout) == 0) perror("fwrite"); + printf("\n"); + } else { + printf("%lld\n", value); } + printf("\n"); + } - printf("Iterate list from 0 to end:\n"); - { - zl = createList(); - p = ziplistIndex(zl, 0); - while (ziplistGet(p, &entry, &elen, &value)) { - printf("Entry: "); - if (entry) { - if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite"); - } else { - printf("%lld", value); - } - p = ziplistNext(zl,p); - printf("\n"); - } - printf("\n"); + printf("Get element at index -4 (first element):\n"); + { + zl = createList(); + p = ziplistIndex(zl, -4); + if (!ziplistGet(p, &entry, &elen, &value)) { + printf("ERROR: Could not access index -4\n"); + return 1; } - - printf("Iterate list from 1 to end:\n"); - { - zl = createList(); - p = ziplistIndex(zl, 1); - while (ziplistGet(p, &entry, &elen, &value)) { - printf("Entry: "); - if (entry) { - if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite"); - } else { - printf("%lld", value); - } - p = ziplistNext(zl,p); - printf("\n"); - } - printf("\n"); + if (entry) { + if (elen && fwrite(entry, elen, 1, stdout) == 0) perror("fwrite"); + printf("\n"); + } else { + printf("%lld\n", value); } + printf("\n"); + } - printf("Iterate list from 2 to end:\n"); - { - zl = createList(); - p = ziplistIndex(zl, 2); - while (ziplistGet(p, &entry, &elen, &value)) { - printf("Entry: "); - if (entry) { - if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite"); - } else { - printf("%lld", value); - } - p = ziplistNext(zl,p); - printf("\n"); - } - printf("\n"); + printf("Get element at index -5 (reverse out of range):\n"); + { + zl = createList(); + p = ziplistIndex(zl, -5); + if (p == NULL) { + printf("No entry\n"); + } else { + printf("ERROR: Out of range index should return NULL, returned offset: %ld\n", p - zl); + return 1; } + printf("\n"); + } - printf("Iterate starting out of range:\n"); - { - zl = createList(); - p = ziplistIndex(zl, 4); - if (!ziplistGet(p, &entry, &elen, &value)) { - printf("No entry\n"); - } else { - printf("ERROR\n"); - } - printf("\n"); + printf("Iterate list from 0 to end:\n"); + { + zl = createList(); + p = ziplistIndex(zl, 0); + while (ziplistGet(p, &entry, &elen, &value)) { + printf("Entry: "); + if (entry) { + if (elen && fwrite(entry, elen, 1, stdout) == 0) perror("fwrite"); + } else { + printf("%lld", value); + } + p = ziplistNext(zl, p); + printf("\n"); } + printf("\n"); + } - printf("Iterate from back to front:\n"); - { - zl = createList(); - p = ziplistIndex(zl, -1); - while (ziplistGet(p, &entry, &elen, &value)) { - printf("Entry: "); - if (entry) { - if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite"); - } else { - printf("%lld", value); - } - p = ziplistPrev(zl,p); - printf("\n"); - } - printf("\n"); + printf("Iterate list from 1 to end:\n"); + { + zl = createList(); + p = ziplistIndex(zl, 1); + while (ziplistGet(p, &entry, &elen, &value)) { + printf("Entry: "); + if (entry) { + if (elen && fwrite(entry, elen, 1, stdout) == 0) perror("fwrite"); + } else { + printf("%lld", value); + } + p = ziplistNext(zl, p); + printf("\n"); } + printf("\n"); + } - printf("Iterate from back to front, deleting all items:\n"); - { - zl = createList(); - p = ziplistIndex(zl, -1); - while (ziplistGet(p, &entry, &elen, &value)) { - printf("Entry: "); - if (entry) { - if (elen && fwrite(entry,elen,1,stdout) == 0) perror("fwrite"); - } else { - printf("%lld", value); - } - zl = ziplistDelete(zl,&p); - p = ziplistPrev(zl,p); - printf("\n"); - } - printf("\n"); + printf("Iterate list from 2 to end:\n"); + { + zl = createList(); + p = ziplistIndex(zl, 2); + while (ziplistGet(p, &entry, &elen, &value)) { + printf("Entry: "); + if (entry) { + if (elen && fwrite(entry, elen, 1, stdout) == 0) perror("fwrite"); + } else { + printf("%lld", value); + } + p = ziplistNext(zl, p); + printf("\n"); } + printf("\n"); + } - printf("Delete inclusive range 0,0:\n"); - { - zl = createList(); - zl = ziplistDeleteRange(zl, 0, 1); - ziplistRepr(zl); + printf("Iterate starting out of range:\n"); + { + zl = createList(); + p = ziplistIndex(zl, 4); + if (!ziplistGet(p, &entry, &elen, &value)) { + printf("No entry\n"); + } else { + printf("ERROR\n"); } + printf("\n"); + } - printf("Delete inclusive range 0,1:\n"); - { - zl = createList(); - zl = ziplistDeleteRange(zl, 0, 2); - ziplistRepr(zl); + printf("Iterate from back to front:\n"); + { + zl = createList(); + p = ziplistIndex(zl, -1); + while (ziplistGet(p, &entry, &elen, &value)) { + printf("Entry: "); + if (entry) { + if (elen && fwrite(entry, elen, 1, stdout) == 0) perror("fwrite"); + } else { + printf("%lld", value); + } + p = ziplistPrev(zl, p); + printf("\n"); } + printf("\n"); + } - printf("Delete inclusive range 1,2:\n"); - { - zl = createList(); - zl = ziplistDeleteRange(zl, 1, 2); - ziplistRepr(zl); + printf("Iterate from back to front, deleting all items:\n"); + { + zl = createList(); + p = ziplistIndex(zl, -1); + while (ziplistGet(p, &entry, &elen, &value)) { + printf("Entry: "); + if (entry) { + if (elen && fwrite(entry, elen, 1, stdout) == 0) perror("fwrite"); + } else { + printf("%lld", value); + } + zl = ziplistDelete(zl, &p); + p = ziplistPrev(zl, p); + printf("\n"); } + printf("\n"); + } - printf("Delete with start index out of range:\n"); - { - zl = createList(); - zl = ziplistDeleteRange(zl, 5, 1); - ziplistRepr(zl); - } + printf("Delete inclusive range 0,0:\n"); + { + zl = createList(); + zl = ziplistDeleteRange(zl, 0, 1); + ziplistRepr(zl); + } - printf("Delete with num overflow:\n"); - { - zl = createList(); - zl = ziplistDeleteRange(zl, 1, 5); - ziplistRepr(zl); - } + printf("Delete inclusive range 0,1:\n"); + { + zl = createList(); + zl = ziplistDeleteRange(zl, 0, 2); + ziplistRepr(zl); + } + + printf("Delete inclusive range 1,2:\n"); + { + zl = createList(); + zl = ziplistDeleteRange(zl, 1, 2); + ziplistRepr(zl); + } + + printf("Delete with start index out of range:\n"); + { + zl = createList(); + zl = ziplistDeleteRange(zl, 5, 1); + ziplistRepr(zl); + } + + printf("Delete with num overflow:\n"); + { + zl = createList(); + zl = ziplistDeleteRange(zl, 1, 5); + ziplistRepr(zl); + } - printf("Delete foo while iterating:\n"); - { - zl = createList(); - p = ziplistIndex(zl,0); - while (ziplistGet(p,&entry,&elen,&value)) { - if (entry && strncmp("foo",(char*)entry,elen) == 0) { - printf("Delete foo\n"); - zl = ziplistDelete(zl,&p); - } else { - printf("Entry: "); - if (entry) { - if (elen && fwrite(entry,elen,1,stdout) == 0) - perror("fwrite"); - } else { - printf("%lld",value); - } - p = ziplistNext(zl,p); - printf("\n"); - } + printf("Delete foo while iterating:\n"); + { + zl = createList(); + p = ziplistIndex(zl, 0); + while (ziplistGet(p, &entry, &elen, &value)) { + if (entry && strncmp("foo", (char *)entry, elen) == 0) { + printf("Delete foo\n"); + zl = ziplistDelete(zl, &p); + } else { + printf("Entry: "); + if (entry) { + if (elen && fwrite(entry, elen, 1, stdout) == 0) perror("fwrite"); + } else { + printf("%lld", value); } + p = ziplistNext(zl, p); printf("\n"); - ziplistRepr(zl); + } } + printf("\n"); + ziplistRepr(zl); + } + + printf("Regression test for >255 byte strings:\n"); + { + char v1[257], v2[257]; + memset(v1, 'x', 256); + memset(v2, 'y', 256); + zl = ziplistNew(); + zl = ziplistPush(zl, (unsigned char *)v1, strlen(v1), ZIPLIST_TAIL); + zl = ziplistPush(zl, (unsigned char *)v2, strlen(v2), ZIPLIST_TAIL); + + /* Pop values again and compare their value. */ + p = ziplistIndex(zl, 0); + assert(ziplistGet(p, &entry, &elen, &value)); + assert(strncmp(v1, (char *)entry, elen) == 0); + p = ziplistIndex(zl, 1); + assert(ziplistGet(p, &entry, &elen, &value)); + assert(strncmp(v2, (char *)entry, elen) == 0); + printf("SUCCESS\n\n"); + } + + printf("Regression test deleting next to last entries:\n"); + { + char v[3][257]; + zlentry e[3]; + int i; - printf("Regression test for >255 byte strings:\n"); - { - char v1[257],v2[257]; - memset(v1,'x',256); - memset(v2,'y',256); - zl = ziplistNew(); - zl = ziplistPush(zl,(unsigned char*)v1,strlen(v1),ZIPLIST_TAIL); - zl = ziplistPush(zl,(unsigned char*)v2,strlen(v2),ZIPLIST_TAIL); - - /* Pop values again and compare their value. */ - p = ziplistIndex(zl,0); - assert(ziplistGet(p,&entry,&elen,&value)); - assert(strncmp(v1,(char*)entry,elen) == 0); - p = ziplistIndex(zl,1); - assert(ziplistGet(p,&entry,&elen,&value)); - assert(strncmp(v2,(char*)entry,elen) == 0); - printf("SUCCESS\n\n"); + for (i = 0; i < (sizeof(v) / sizeof(v[0])); i++) { + memset(v[i], 'a' + i, sizeof(v[0])); } - printf("Regression test deleting next to last entries:\n"); - { - char v[3][257]; - zlentry e[3]; - int i; + v[0][256] = '\0'; + v[1][1] = '\0'; + v[2][256] = '\0'; - for (i = 0; i < (sizeof(v)/sizeof(v[0])); i++) { - memset(v[i], 'a' + i, sizeof(v[0])); - } + zl = ziplistNew(); + for (i = 0; i < (sizeof(v) / sizeof(v[0])); i++) { + zl = ziplistPush(zl, (unsigned char *)v[i], strlen(v[i]), ZIPLIST_TAIL); + } - v[0][256] = '\0'; - v[1][ 1] = '\0'; - v[2][256] = '\0'; + verify(zl, e); - zl = ziplistNew(); - for (i = 0; i < (sizeof(v)/sizeof(v[0])); i++) { - zl = ziplistPush(zl, (unsigned char *) v[i], strlen(v[i]), ZIPLIST_TAIL); - } + assert(e[0].prevrawlensize == 1); + assert(e[1].prevrawlensize == 5); + assert(e[2].prevrawlensize == 1); - verify(zl, e); + /* Deleting entry 1 will increase `prevrawlensize` for entry 2 */ + unsigned char *p = e[1].p; + zl = ziplistDelete(zl, &p); - assert(e[0].prevrawlensize == 1); - assert(e[1].prevrawlensize == 5); - assert(e[2].prevrawlensize == 1); + verify(zl, e); - /* Deleting entry 1 will increase `prevrawlensize` for entry 2 */ - unsigned char *p = e[1].p; - zl = ziplistDelete(zl, &p); + assert(e[0].prevrawlensize == 1); + assert(e[1].prevrawlensize == 5); - verify(zl, e); + printf("SUCCESS\n\n"); + } - assert(e[0].prevrawlensize == 1); - assert(e[1].prevrawlensize == 5); + printf("Create long list and check indices:\n"); + { + zl = ziplistNew(); + char buf[32]; + int i, len; + for (i = 0; i < 1000; i++) { + len = sprintf(buf, "%d", i); + zl = ziplistPush(zl, (unsigned char *)buf, len, ZIPLIST_TAIL); + } + for (i = 0; i < 1000; i++) { + p = ziplistIndex(zl, i); + assert(ziplistGet(p, NULL, NULL, &value)); + assert(i == value); + + p = ziplistIndex(zl, -i - 1); + assert(ziplistGet(p, NULL, NULL, &value)); + assert(999 - i == value); + } + printf("SUCCESS\n\n"); + } - printf("SUCCESS\n\n"); + printf("Compare strings with ziplist entries:\n"); + { + zl = createList(); + p = ziplistIndex(zl, 0); + if (!ziplistCompare(p, (unsigned char *)"hello", 5)) { + printf("ERROR: not \"hello\"\n"); + return 1; + } + if (ziplistCompare(p, (unsigned char *)"hella", 5)) { + printf("ERROR: \"hella\"\n"); + return 1; } - printf("Create long list and check indices:\n"); - { - zl = ziplistNew(); - char buf[32]; - int i,len; - for (i = 0; i < 1000; i++) { - len = sprintf(buf,"%d",i); - zl = ziplistPush(zl,(unsigned char*)buf,len,ZIPLIST_TAIL); - } - for (i = 0; i < 1000; i++) { - p = ziplistIndex(zl,i); - assert(ziplistGet(p,NULL,NULL,&value)); - assert(i == value); - - p = ziplistIndex(zl,-i-1); - assert(ziplistGet(p,NULL,NULL,&value)); - assert(999-i == value); - } - printf("SUCCESS\n\n"); + p = ziplistIndex(zl, 3); + if (!ziplistCompare(p, (unsigned char *)"1024", 4)) { + printf("ERROR: not \"1024\"\n"); + return 1; } + if (ziplistCompare(p, (unsigned char *)"1025", 4)) { + printf("ERROR: \"1025\"\n"); + return 1; + } + printf("SUCCESS\n\n"); + } - printf("Compare strings with ziplist entries:\n"); - { - zl = createList(); - p = ziplistIndex(zl,0); - if (!ziplistCompare(p,(unsigned char*)"hello",5)) { - printf("ERROR: not \"hello\"\n"); - return 1; - } - if (ziplistCompare(p,(unsigned char*)"hella",5)) { - printf("ERROR: \"hella\"\n"); - return 1; + printf("Stress with random payloads of different encoding:\n"); + { + int i, j, len, where; + unsigned char *p; + char buf[1024]; + int buflen; + list *ref; + listNode *refnode; + + /* Hold temp vars from ziplist */ + unsigned char *sstr; + unsigned int slen; + long long sval; + + for (i = 0; i < 20000; i++) { + zl = ziplistNew(); + ref = listCreate(); + listSetFreeMethod(ref, sdsfree); + len = rand() % 256; + + /* Create lists */ + for (j = 0; j < len; j++) { + where = (rand() & 1) ? ZIPLIST_HEAD : ZIPLIST_TAIL; + if (rand() % 2) { + buflen = randstring(buf, 1, sizeof(buf) - 1); + } else { + switch (rand() % 3) { + case 0: + buflen = sprintf(buf, "%lld", (0LL + rand()) >> 20); + break; + case 1: + buflen = sprintf(buf, "%lld", (0LL + rand())); + break; + case 2: + buflen = sprintf(buf, "%lld", (0LL + rand()) << 20); + break; + default: + assert(NULL); + } } - p = ziplistIndex(zl,3); - if (!ziplistCompare(p,(unsigned char*)"1024",4)) { - printf("ERROR: not \"1024\"\n"); - return 1; - } - if (ziplistCompare(p,(unsigned char*)"1025",4)) { - printf("ERROR: \"1025\"\n"); - return 1; - } - printf("SUCCESS\n\n"); - } + /* Add to ziplist */ + zl = ziplistPush(zl, (unsigned char *)buf, buflen, where); - printf("Stress with random payloads of different encoding:\n"); - { - int i,j,len,where; - unsigned char *p; - char buf[1024]; - int buflen; - list *ref; - listNode *refnode; - - /* Hold temp vars from ziplist */ - unsigned char *sstr; - unsigned int slen; - long long sval; - - for (i = 0; i < 20000; i++) { - zl = ziplistNew(); - ref = listCreate(); - listSetFreeMethod(ref,sdsfree); - len = rand() % 256; - - /* Create lists */ - for (j = 0; j < len; j++) { - where = (rand() & 1) ? ZIPLIST_HEAD : ZIPLIST_TAIL; - if (rand() % 2) { - buflen = randstring(buf,1,sizeof(buf)-1); - } else { - switch(rand() % 3) { - case 0: - buflen = sprintf(buf,"%lld",(0LL + rand()) >> 20); - break; - case 1: - buflen = sprintf(buf,"%lld",(0LL + rand())); - break; - case 2: - buflen = sprintf(buf,"%lld",(0LL + rand()) << 20); - break; - default: - assert(NULL); - } - } - - /* Add to ziplist */ - zl = ziplistPush(zl, (unsigned char*)buf, buflen, where); - - /* Add to reference list */ - if (where == ZIPLIST_HEAD) { - listAddNodeHead(ref,sdsnewlen(buf, buflen)); - } else if (where == ZIPLIST_TAIL) { - listAddNodeTail(ref,sdsnewlen(buf, buflen)); - } else { - assert(NULL); - } - } - - assert(listLength(ref) == ziplistLen(zl)); - for (j = 0; j < len; j++) { - /* Naive way to get elements, but similar to the stresser - * executed from the Tcl test suite. */ - p = ziplistIndex(zl,j); - refnode = listIndex(ref,j); - - assert(ziplistGet(p,&sstr,&slen,&sval)); - if (sstr == NULL) { - buflen = sprintf(buf,"%lld",sval); - } else { - buflen = slen; - memcpy(buf,sstr,buflen); - buf[buflen] = '\0'; - } - assert(memcmp(buf,listNodeValue(refnode),buflen) == 0); - } - zfree(zl); - listRelease(ref); + /* Add to reference list */ + if (where == ZIPLIST_HEAD) { + listAddNodeHead(ref, sdsnewlen(buf, buflen)); + } else if (where == ZIPLIST_TAIL) { + listAddNodeTail(ref, sdsnewlen(buf, buflen)); + } else { + assert(NULL); } - printf("SUCCESS\n\n"); + } + + assert(listLength(ref) == ziplistLen(zl)); + for (j = 0; j < len; j++) { + /* Naive way to get elements, but similar to the stresser + * executed from the Tcl test suite. */ + p = ziplistIndex(zl, j); + refnode = listIndex(ref, j); + + assert(ziplistGet(p, &sstr, &slen, &sval)); + if (sstr == NULL) { + buflen = sprintf(buf, "%lld", sval); + } else { + buflen = slen; + memcpy(buf, sstr, buflen); + buf[buflen] = '\0'; + } + assert(memcmp(buf, listNodeValue(refnode), buflen) == 0); + } + zfree(zl); + listRelease(ref); } + printf("SUCCESS\n\n"); + } - printf("Stress with variable ziplist size:\n"); - { - stress(ZIPLIST_HEAD,100000,16384,256); - stress(ZIPLIST_TAIL,100000,16384,256); - } + printf("Stress with variable ziplist size:\n"); + { + stress(ZIPLIST_HEAD, 100000, 16384, 256); + stress(ZIPLIST_TAIL, 100000, 16384, 256); + } - return 0; + return 0; } #endif diff --git a/src/server_command.cc b/src/server_command.cc index 5bdac942a..742b6a262 100644 --- a/src/server_command.cc +++ b/src/server_command.cc @@ -76,8 +76,8 @@ PError flushall(const std::vector& params, UnboundedBuffer* reply) { PError bgsave(const std::vector& params, UnboundedBuffer* reply) { if (g_qdbPid != -1) { - FormatBulk("-ERR Background save already in progress", - sizeof "-ERR Background save already in progress" - 1, reply); + FormatBulk("-ERR Background save already in progress", sizeof "-ERR Background save already in progress" - 1, + reply); return PError_ok; } @@ -101,8 +101,8 @@ PError bgsave(const std::vector& params, UnboundedBuffer* reply) { PError save(const std::vector& params, UnboundedBuffer* reply) { if (g_qdbPid != -1) { - FormatBulk("-ERR Background save already in progress", - sizeof "-ERR Background save already in progress" - 1, reply); + FormatBulk("-ERR Background save already in progress", sizeof "-ERR Background save already in progress" - 1, + reply); return PError_ok; } diff --git a/src/set.h b/src/set.h index f3350a7b6..d60a2eb46 100644 --- a/src/set.h +++ b/src/set.h @@ -16,4 +16,3 @@ using PSet = std::unordered_set >; size_t SScanKey(const PSet& qset, size_t cursor, size_t count, std::vector& res); } // namespace pikiwidb - diff --git a/src/slow_log.h b/src/slow_log.h index d6fee1040..92b29ccb1 100644 --- a/src/slow_log.h +++ b/src/slow_log.h @@ -55,4 +55,3 @@ class PSlowLog { }; } // namespace pikiwidb - diff --git a/src/sorted_set.h b/src/sorted_set.h index ae33b46a9..6adebc4c1 100644 --- a/src/sorted_set.h +++ b/src/sorted_set.h @@ -47,4 +47,3 @@ class PSortedSet { }; } // namespace pikiwidb - diff --git a/src/store.cc b/src/store.cc index 43c5a1c59..289726b2a 100644 --- a/src/store.cc +++ b/src/store.cc @@ -441,9 +441,9 @@ bool PStore::DeleteKey(const PString& key) { size_t ret = 0; // erase() from folly ConcurrentHashmap will throw an exception if hash function crashes try { - ret = db->erase(key); + ret = db->erase(key); } catch (const std::exception& e) { - return false; + return false; } return ret != 0; diff --git a/src/store.h b/src/store.h index 081d2cdcc..510cbe40b 100644 --- a/src/store.h +++ b/src/store.h @@ -187,7 +187,7 @@ class PStore { size_t Size() const { return blockedClients_.size(); } private: - using Clients = std::list, uint64_t, ListPosition> >; + using Clients = std::list, uint64_t, ListPosition>>; using WaitingList = folly::ConcurrentHashMap>; WaitingList blockedClients_; @@ -199,9 +199,9 @@ class PStore { mutable std::vector dbs_; mutable std::vector expiredDBs_; std::vector blockedClients_; - std::vector > backends_; + std::vector> backends_; - using ToSyncDB = folly::ConcurrentHashMap >; + using ToSyncDB = folly::ConcurrentHashMap>; std::vector waitSyncKeys_; int dbno_ = -1; };