diff --git a/extend/lcodec/lcodec.vcxproj b/extend/lcodec/lcodec.vcxproj index 057950c3..ce3bcfab 100644 --- a/extend/lcodec/lcodec.vcxproj +++ b/extend/lcodec/lcodec.vcxproj @@ -7,7 +7,7 @@ - + diff --git a/extend/lcodec/lcodec.vcxproj.filters b/extend/lcodec/lcodec.vcxproj.filters index bd7a67ab..b7e46004 100644 --- a/extend/lcodec/lcodec.vcxproj.filters +++ b/extend/lcodec/lcodec.vcxproj.filters @@ -1,7 +1,7 @@  - + src diff --git a/extend/lcodec/src/bitarray.h b/extend/lcodec/src/bitarray.h deleted file mode 100644 index 8e076570..00000000 --- a/extend/lcodec/src/bitarray.h +++ /dev/null @@ -1,262 +0,0 @@ -#pragma once - -#include -#include - -namespace lcodec { - typedef unsigned int BWORD; - - /* number of bits in a word */ - #define BITS_PER_BWORD (CHAR_BIT * sizeof(BWORD)) - /* gets the word that contains the bit corresponding to a given index i */ - #define I_BWORD(i) ((BWORD)(i) / BITS_PER_BWORD) - /* computes a mask to access the correct bit inside this word */ - #define I_BIT(i) ((BWORD)1 << ((BWORD)(i) % BITS_PER_BWORD)) - /* computes how many words to store n bits */ - #define BWORDS_FOR_BITS(n) (I_BWORD((n) - 1) + 1) - - class bitarray - { - public: - ~bitarray() { - if (values_) { - free(values_); - values_ = nullptr; - } - size_ = 0; - } - - size_t general(size_t nbits) { - values_ = (BWORD*)calloc(BWORDS_FOR_BITS(nbits), sizeof(BWORD)); - if (values_ != nullptr) - return size_ = nbits; - return 0; - } - - /* set ith bit to 1 if b is truthy, else 0 */ - void set_bit(size_t i, size_t b) { - raw_set_bit(check_index(i), b); - } - - /* get ith bit (1 or 0) */ - size_t get_bit(size_t i) { - return raw_get_bit(check_index(i)); - } - - /* 1 -> 0 and 0 -> 1 */ - void flip_bit(size_t i) { - size_t idx = check_index(i); - if (idx < size_) { - BWORD mask; - BWORD* word = get_bit_access(idx, &mask); - *word = (*word & mask) ? (*word & ~mask) : (*word | mask); - } - } - - void flip() { - size_t nwords = BWORDS_FOR_BITS(size_); - for (size_t i = 0; i < nwords; ++i) { - values_[i] = ~values_[i]; - } - for (size_t i = size_; i < nwords * BITS_PER_BWORD; ++i) { - raw_set_bit(i, 0); - } - } - - void fill(bool b) { - BWORD bb = b ? (BWORD)-1 : 0; - size_t nwords = BWORDS_FOR_BITS(size_); - for (size_t i = 0; i < nwords; ++i) { - values_[i] = bb; - } - for (size_t i = size_; i < nwords * BITS_PER_BWORD; ++i) { - raw_set_bit(i, 0); - } - } - - /* resize the array. if new size is bigger, fill the new bit positions with 0. - also set any unused bits to 0 (ie the gap between size and the actual end - of WORDs). returns the new size, or 0 is returned if failed (array unchanged)*/ - size_t resize(size_t nbits) { - if (nbits == size_) - return nbits; - size_t oldwords = BWORDS_FOR_BITS(size_); - size_t newwords = BWORDS_FOR_BITS(nbits); - if (oldwords != newwords) { - BWORD* tmp = (BWORD* )realloc(values_, newwords * sizeof(BWORD)); - if (tmp == nullptr) - return 0; - values_ = tmp; - } - size_ = nbits; - size_t oldbits = size_; - if (nbits < oldbits) { - for (size_t i = nbits; i < newwords * BITS_PER_BWORD; ++i) - raw_set_bit(i, 0); - } else { - /* gap between oldbits and oldwords*BITS_PER_BWORD is guaranteed to be 0 */ - for (size_t i = oldwords; i < newwords; ++i) - values_[i] = 0; - } - return nbits; - } - - void reverse() { - for (size_t i = 0, j = size_ - 1; i < j; ++i, --j) { - int tmp = raw_get_bit(i); - raw_set_bit(i, raw_get_bit(j)); - raw_set_bit(j, tmp); - } - } - - /* copy values from ba to tg */ - void concat(bitarray* tg) { - resize(size_ + tg->size_); - for (size_t i = 0; i < BWORDS_FOR_BITS(size_); ++i) - values_[size_] = tg->values_[i]; - } - - /* copy values from ba to tg */ - bitarray* clone() { - bitarray* ba = new bitarray(); - if (!ba->general(size_)) { - delete ba; - return nullptr; - } - for (size_t i = 0; i < BWORDS_FOR_BITS(size_); ++i) { - ba->values_[i] = values_[i]; - } - return ba; - } - - bitarray* slice(size_t from, size_t to) { - size_t ifrom = check_index(from); - size_t ito = check_index(to, true); - size_t len = ito - ifrom + 1; - bitarray* ba = new bitarray(); - if (!ba->general(len)) { - delete ba; - return nullptr; - } - for(size_t i = 0; i < len; ++i) { - ba->raw_set_bit(i, raw_get_bit(ifrom + i)); - } - return ba; - } - - void from_string(std::string str, size_t i) { - size_t idx = check_index(i); - size_t slen = str.size(); - resize(i + slen); - for (size_t j = 0; j < slen; ++j) - raw_set_bit(idx + j, str[j] != '0'); - } - - template - void from_number(T src, size_t i) { - size_t idx = check_index(i); - size_t tgt = sizeof(T) * CHAR_BIT; - resize(i + tgt); - for (size_t j = idx, k = 0; k < tgt; ++j, ++k) { - T maskt = (T)1 << (T)(tgt - k - 1); - size_t b = !!(src & maskt); - raw_set_bit(j, b); - } - } - - template - T to_number(size_t i) { - T res = 0; - size_t idx = check_index(i); - size_t tgt = sizeof(T) * CHAR_BIT; - for (size_t j = idx, k = 0; k < tgt; ++j, ++k) { - BWORD mask; - BWORD* word = get_bit_access(j, &mask); - T maskt = (T)1 << (T)(tgt - k - 1); - res = (*word & mask) ? (res | maskt) : (res & ~maskt); - } - return res; - } - - std::string to_string(size_t i) { - std::string str = "bitarray<"; - str.append(std::to_string(size_)); - str.append(">["); - for (size_t i = 0; i < size_; ++i) { - str.append(raw_get_bit(i) ? "1," : "0,"); - } - return str; - } - - bool equal(bitarray *r) { - if (size_ != r->size_) - return false; - for (size_t i = 0; i < BWORDS_FOR_BITS(size_); ++i) - if (values_[i] != r->values_[i]) - return false; - return true; - } - - void lshift(size_t s) { - size_t sz = size_; - for (size_t i = 0; i + s < sz; ++i) - raw_set_bit(i, raw_get_bit(i + s)); - for (size_t i = sz > s ? sz - s : 0; i < sz; ++i) - raw_set_bit(i, 0); - } - - void rshift(size_t s) { - size_t sz = size_; - for (size_t i = 0; i + s < sz; ++i) - raw_set_bit(sz - i - 1, raw_get_bit(sz - i - 1 - s)); - for (size_t i = sz > s ? sz - s : 0; i < sz; ++i) - raw_set_bit(sz - i - 1, 0); - } - - size_t length() { - return size_; - } - - private: - size_t check_index(size_t i, bool tail = false) { - if (tail) { - return (i > 0 && i <= size_) ? i - 1 : size_ - 1; - } - return i > 0 ? i - 1 : 0; - } - - /* set ith bit to 1 if b is truthy, else 0 */ - void raw_set_bit(size_t i, size_t b) { - if (i < size_) { - BWORD mask; - BWORD* word = get_bit_access(i, &mask); - if (b) - *word |= mask; /* set bit */ - else - *word &= ~mask; /* reset bit */ - } - } - - /* get ith bit (1 or 0) */ - size_t raw_get_bit(size_t i) { - if (i < size_) { - BWORD mask; - BWORD* word = get_bit_access(i, &mask); - return (*word & mask) ? 1 : 0; - } - return -1; - } - - /* given an index, returns the word address and the mask to access the bit */ - BWORD* get_bit_access(size_t i, BWORD* mask) { - if (mask != nullptr) - *mask = I_BIT(i); - return &values_[I_BWORD(i)]; - } - - private: - size_t size_; - BWORD* values_; /* uses little endian to store bits */ - }; - -} diff --git a/extend/lcodec/src/bitset.h b/extend/lcodec/src/bitset.h new file mode 100644 index 00000000..3bdaae7b --- /dev/null +++ b/extend/lcodec/src/bitset.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include + +namespace lcodec { + + template + std::string lua_bitset_new(std::string val) { + std::bitset bit(val); + return bit.to_string(); + } + + template + bool lua_bitset_get(std::string val, size_t pos) { + std::bitset bit(val); + return bit[pos - 1]; + } + + template + std::string lua_bitset_set(std::string val, size_t pos, bool bval) { + std::bitset bit(val); + return bit.set(pos - 1, bval).to_string(); + } + + template + std::string lua_bitset_flip(std::string val, size_t pos) { + std::bitset bit(val); + return bit.flip(pos - 1).to_string(); + } + + template + std::string lua_bitset_reset(std::string val, size_t pos) { + std::bitset bit(val); + if (pos == 0) { + return bit.reset().to_string(); + } + return bit.reset(pos - 1).to_string(); + } + + template + bool lua_bitset_check(std::string val, size_t len) { + if (len > N) return false; + std::bitset bit(val); + for (size_t i = 0; i < len; ++i) { + if (!bit[i]) return false; + } + return true; + } +} diff --git a/extend/lcodec/src/lcodec.cpp b/extend/lcodec/src/lcodec.cpp index 72c2ac60..d488d730 100644 --- a/extend/lcodec/src/lcodec.cpp +++ b/extend/lcodec/src/lcodec.cpp @@ -41,20 +41,10 @@ namespace lcodec { codec->set_buff(&thread_buff); return codec; } - - static bitarray* lbarray(lua_State* L, size_t nbits) { - bitarray* barray = new bitarray(); - if (!barray->general(nbits)) { - delete barray; - return nullptr; - } - return barray; - } luakit::lua_table open_lcodec(lua_State* L) { luakit::kit_state kit_state(L); auto llcodec = kit_state.new_table("codec"); - llcodec.set_function("bitarray", lbarray); llcodec.set_function("guid_new", guid_new); llcodec.set_function("guid_string", guid_string); llcodec.set_function("guid_tostring", guid_tostring); @@ -76,34 +66,37 @@ namespace lcodec { llcodec.set_function("rediscodec", rds_codec); llcodec.set_function("wsscodec", wss_codec); llcodec.set_function("url_encode", url_encode); - llcodec.set_function("url_decode", url_decode); - - kit_state.new_class( - "flip", &bitarray::flip, - "fill", &bitarray::fill, - "equal", &bitarray::equal, - "clone", &bitarray::clone, - "slice", &bitarray::slice, - "concat", &bitarray::concat, - "lshift", &bitarray::lshift, - "rshift", &bitarray::rshift, - "length", &bitarray::length, - "resize", &bitarray::resize, - "reverse", &bitarray::reverse, - "set_bit", &bitarray::set_bit, - "get_bit", &bitarray::get_bit, - "flip_bit", &bitarray::flip_bit, - "to_string", &bitarray::to_string, - "from_string", &bitarray::from_string, - "to_uint8", &bitarray::to_number, - "to_uint16", &bitarray::to_number, - "to_uint32", &bitarray::to_number, - "to_uint64", &bitarray::to_number, - "from_uint8", &bitarray::from_number, - "from_uint16", &bitarray::from_number, - "from_uint32", &bitarray::from_number, - "from_uint64", &bitarray::from_number - ); + llcodec.set_function("url_decode", url_decode); + llcodec.set_function("bit32_new", lua_bitset_new<32>); + llcodec.set_function("bit64_new", lua_bitset_new<64>); + llcodec.set_function("bit128_new", lua_bitset_new<128>); + llcodec.set_function("bit256_new", lua_bitset_new<256>); + llcodec.set_function("bit512_new", lua_bitset_new<512>); + llcodec.set_function("bit32_get", lua_bitset_get<32>); + llcodec.set_function("bit64_get", lua_bitset_get<64>); + llcodec.set_function("bit128_get", lua_bitset_get<128>); + llcodec.set_function("bit256_get", lua_bitset_get<256>); + llcodec.set_function("bit512_get", lua_bitset_get<512>); + llcodec.set_function("bit32_set", lua_bitset_set<32>); + llcodec.set_function("bit64_set", lua_bitset_set<64>); + llcodec.set_function("bit128_set", lua_bitset_set<128>); + llcodec.set_function("bit256_set", lua_bitset_set<256>); + llcodec.set_function("bit512_set", lua_bitset_set<512>); + llcodec.set_function("bit32_flip", lua_bitset_flip<32>); + llcodec.set_function("bit64_flip", lua_bitset_flip<64>); + llcodec.set_function("bit128_flip", lua_bitset_flip<128>); + llcodec.set_function("bit256_flip", lua_bitset_flip<256>); + llcodec.set_function("bit512_flip", lua_bitset_flip<512>); + llcodec.set_function("bit32_reset", lua_bitset_reset<32>); + llcodec.set_function("bit64_reset", lua_bitset_reset<64>); + llcodec.set_function("bit128_reset", lua_bitset_reset<128>); + llcodec.set_function("bit256_reset", lua_bitset_reset<256>); + llcodec.set_function("bit512_reset", lua_bitset_reset<512>); + llcodec.set_function("bit32_check", lua_bitset_check<32>); + llcodec.set_function("bit64_check", lua_bitset_check<64>); + llcodec.set_function("bit128_check", lua_bitset_check<128>); + llcodec.set_function("bit256_check", lua_bitset_check<256>); + llcodec.set_function("bit512_check", lua_bitset_check<512>); return llcodec; } } diff --git a/extend/lcodec/src/lcodec.h b/extend/lcodec/src/lcodec.h index eafa4c3c..aa277d4f 100644 --- a/extend/lcodec/src/lcodec.h +++ b/extend/lcodec/src/lcodec.h @@ -10,4 +10,4 @@ #include "redis.h" #include "mysql.h" #include "websocket.h" -#include "bitarray.h" +#include "bitset.h" diff --git a/server/test.lua b/server/test.lua index da7f8892..9d8bed96 100644 --- a/server/test.lua +++ b/server/test.lua @@ -26,12 +26,12 @@ quanta.startup(function()--初始化test import("test/worker_test.lua") import("test/lock_test.lua") import("test/detour_test.lua") - import("test/bitarray_test.lua") + import("test/bitset_test.lua") import("test/lmdb_test.lua") import("test/unqlite_test.lua") import("test/sqlite_test.lua") import("test/ssl_test.lua") import("test/xml_test.lua") ]] - import("test/mongo_test.lua") + import("test/bitset_test.lua") end) diff --git a/server/test/bitarray_test.lua b/server/test/bitarray_test.lua deleted file mode 100644 index 8a0311ac..00000000 --- a/server/test/bitarray_test.lua +++ /dev/null @@ -1,30 +0,0 @@ ---bitarray_test.lua - -local log_debug = logger.debug - -local array = codec.bitarray(32) -log_debug("array1: {}", array.to_string()) -array.fill(1) -log_debug("array11: {}", array.to_string()) -array.flip(1) -log_debug("array12: {}", array.to_string()) -array.flip_bit(3) -log_debug("array13: {}-{}", array.to_string(), array.get_bit(3)) -array.from_uint32(65535) -log_debug("array2: {}-{}", array.to_string(), array.to_uint32()) -array.rshift(1) -log_debug("array3: {}-{}", array.to_string(), array.to_uint32()) -array.lshift(1) -log_debug("array4: {}-{}", array.to_string(), array.to_uint32()) -array.set_bit(32, 1) -local a2 = array.clone() -log_debug("array5: {}", a2.to_string()) -local a3 = a2.slice(1, 16) -log_debug("array51: {}", a3.to_string()) -local a4 = a2.slice(17) -log_debug("array52: {}", a4.to_string()) -a4.concat(a3) -log_debug("array6: {}", a4.to_string()) -a4.reverse() -log_debug("array7: {}", a4.to_string()) -log_debug("array8: {}-{}", a4.equal(a2), a3.equal(a2)) diff --git a/server/test/bitset_test.lua b/server/test/bitset_test.lua new file mode 100644 index 00000000..93cda0b5 --- /dev/null +++ b/server/test/bitset_test.lua @@ -0,0 +1,19 @@ +--bitset_test.lua + +local log_debug = logger.debug + +local bval = codec.bit32_new() +log_debug("bit32_new: {}", bval) +local fval = codec.bit32_flip(bval, 3) +log_debug("bit32_flip: {}-{}", bval, fval) +log_debug("bit32_get: {}-{}", codec.bit32_get(fval, 3), codec.bit32_get(fval, 2)) + +local bval2 = codec.bit32_new("010000101") +log_debug("bit32_new: {}", bval2) +local sval = codec.bit32_set(bval2, 4, true) +log_debug("bit32_set: {}-{}", bval2, sval) +local sval2 = codec.bit32_set(sval, 2, true) +log_debug("bit32_set: {}-{}", bval2, sval2) +log_debug("bit32_check 4: {}", codec.bit32_check(sval2, 4)) +log_debug("bit32_check 5: {}", codec.bit32_check(sval2, 5)) +