mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-34075: Binlog-in-engine: Some test and review fixes
Enable binlog_in_engine as a default suite. Fix embedded and Windows build failures. Use sql_print_(error|warning) over ib::error() and ib::warn(). Use small_vector<> for the innodb_binlog_oob_reader instead of a custom implementation. Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
This commit is contained in:
@@ -180,6 +180,7 @@ my @DEFAULT_SUITES= qw(
|
|||||||
atomic-
|
atomic-
|
||||||
binlog-
|
binlog-
|
||||||
binlog_encryption-
|
binlog_encryption-
|
||||||
|
binlog_in_engine-
|
||||||
client-
|
client-
|
||||||
csv-
|
csv-
|
||||||
compat/oracle-
|
compat/oracle-
|
||||||
|
@@ -3375,7 +3375,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (reset_transmit_packet(info, info->flags, &ev_offset, &info->errmsg) ||
|
if (reset_transmit_packet(info, info->flags, &ev_offset, &info->errmsg) ||
|
||||||
fake_format_description_event(info, info->fdev, &info->errmsg, pos))
|
fake_format_description_event(info, info->fdev, &info->errmsg,
|
||||||
|
(uint32_t)pos))
|
||||||
{
|
{
|
||||||
info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
|
||||||
goto err;
|
goto err;
|
||||||
|
@@ -184,18 +184,18 @@ fsp_binlog_open(const char *file_name, pfs_os_file_t fh,
|
|||||||
restart.
|
restart.
|
||||||
*/
|
*/
|
||||||
if (!os_file_set_size(file_name, fh, binlog_size, false)) {
|
if (!os_file_set_size(file_name, fh, binlog_size, false)) {
|
||||||
ib::warn() << "Failed to change the size of InnoDB binlog file " <<
|
sql_print_warning("Failed to change the size of InnoDB binlog file '%s' "
|
||||||
file_name << " from " << file_size << " to " << binlog_size <<
|
"from %zu to %zu bytes (error code: %d)", file_name,
|
||||||
" bytes (error code: " << errno << ").";
|
file_size, (size_t)binlog_size, errno);
|
||||||
} else {
|
} else {
|
||||||
file_size= (size_t)binlog_size;
|
file_size= (size_t)binlog_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (file_size < 2*page_size)
|
if (file_size < 2*page_size)
|
||||||
{
|
{
|
||||||
ib::warn() << "InnoDB binlog file number " << file_no << " is too short"
|
sql_print_warning("InnoDB binlog file number %llu is too short (%zu bytes), "
|
||||||
" (" << file_size << " bytes), should be at least " << 2*page_size <<
|
"should be at least %u bytes",
|
||||||
" bytes.";
|
file_no, file_size, 2*page_size);
|
||||||
os_file_close(fh);
|
os_file_close(fh);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,7 @@ fsp_binlog_open(const char *file_name, pfs_os_file_t fh,
|
|||||||
|
|
||||||
dberr_t err= os_file_read(IORequestRead, fh, page_buf, 0, page_size, nullptr);
|
dberr_t err= os_file_read(IORequestRead, fh, page_buf, 0, page_size, nullptr);
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
ib::warn() << "Unable to read first page of file " << file_name;
|
sql_print_warning("Unable to read first page of file '%s'", file_name);
|
||||||
aligned_free(page_buf);
|
aligned_free(page_buf);
|
||||||
os_file_close(fh);
|
os_file_close(fh);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -220,9 +220,8 @@ fsp_binlog_open(const char *file_name, pfs_os_file_t fh,
|
|||||||
/* ToDo: Maybe use leaner page format for binlog tablespace? */
|
/* ToDo: Maybe use leaner page format for binlog tablespace? */
|
||||||
uint32_t id1= mach_read_from_4(FIL_PAGE_SPACE_ID + page_buf);
|
uint32_t id1= mach_read_from_4(FIL_PAGE_SPACE_ID + page_buf);
|
||||||
if (id1 != space_id) {
|
if (id1 != space_id) {
|
||||||
ib::warn() << "Binlog file " << file_name <<
|
sql_print_warning("Binlog file %s has inconsistent tablespace id %u "
|
||||||
" has inconsistent tablespace id " << id1 <<
|
"(expected %u)", file_name, id1, space_id);
|
||||||
" (expected " << space_id << ")";
|
|
||||||
aligned_free(page_buf);
|
aligned_free(page_buf);
|
||||||
os_file_close(fh);
|
os_file_close(fh);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -298,7 +297,7 @@ dberr_t fsp_binlog_tablespace_create(uint64_t file_no, fil_space_t **new_space)
|
|||||||
/* We created the binlog file and now write it full of zeros */
|
/* We created the binlog file and now write it full of zeros */
|
||||||
if (!os_file_set_size(name, fh,
|
if (!os_file_set_size(name, fh,
|
||||||
os_offset_t{size} << srv_page_size_shift)) {
|
os_offset_t{size} << srv_page_size_shift)) {
|
||||||
ib::error() << "Unable to allocate " << name;
|
sql_print_error("Unable to allocate file %s", name);
|
||||||
os_file_close(fh);
|
os_file_close(fh);
|
||||||
os_file_delete(innodb_data_file_key, name);
|
os_file_delete(innodb_data_file_key, name);
|
||||||
return DB_ERROR;
|
return DB_ERROR;
|
||||||
@@ -625,8 +624,8 @@ int
|
|||||||
binlog_chunk_reader::read_error_corruption(uint64_t file_no, uint64_t page_no,
|
binlog_chunk_reader::read_error_corruption(uint64_t file_no, uint64_t page_no,
|
||||||
const char *msg)
|
const char *msg)
|
||||||
{
|
{
|
||||||
ib::error() << "Corrupt binlog found on page " << page_no <<
|
sql_print_error("Corrupt binlog found on page %llu in binlog number %llu: "
|
||||||
" in binlog number " << file_no << ": " << msg;
|
"%s", page_no, file_no, msg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@ InnoDB implementation of binlog.
|
|||||||
#include "mtr0log.h"
|
#include "mtr0log.h"
|
||||||
#include "fsp0fsp.h"
|
#include "fsp0fsp.h"
|
||||||
#include "trx0trx.h"
|
#include "trx0trx.h"
|
||||||
|
#include "small_vector.h"
|
||||||
|
|
||||||
#include "rpl_gtid_base.h"
|
#include "rpl_gtid_base.h"
|
||||||
#include "handler.h"
|
#include "handler.h"
|
||||||
@@ -159,16 +160,9 @@ class innodb_binlog_oob_reader {
|
|||||||
a prior tree that must be traversed first.
|
a prior tree that must be traversed first.
|
||||||
*/
|
*/
|
||||||
bool is_leftmost;
|
bool is_leftmost;
|
||||||
} init_stack[8], *stack;
|
};
|
||||||
|
small_vector<stack_entry, 8>stack;
|
||||||
|
|
||||||
/*
|
|
||||||
If the stack_len is == sizeof(init_stack)/sizeof(init_stack[0]), then we
|
|
||||||
are using the embedded stack memory. Otherwise we are using a dynamically
|
|
||||||
allocated stack that must be freed.
|
|
||||||
*/
|
|
||||||
uint32_t stack_len;
|
|
||||||
/* Current top of stack. */
|
|
||||||
uint32_t stack_top;
|
|
||||||
/* State machine current state. */
|
/* State machine current state. */
|
||||||
enum oob_states state;
|
enum oob_states state;
|
||||||
|
|
||||||
@@ -176,13 +170,12 @@ public:
|
|||||||
innodb_binlog_oob_reader();
|
innodb_binlog_oob_reader();
|
||||||
~innodb_binlog_oob_reader();
|
~innodb_binlog_oob_reader();
|
||||||
|
|
||||||
bool start_traversal(uint64_t file_no, uint64_t offset);
|
void start_traversal(uint64_t file_no, uint64_t offset);
|
||||||
bool oob_traversal_done() { return stack_top == 0; }
|
bool oob_traversal_done() { return stack.empty(); }
|
||||||
int read_data(binlog_chunk_reader *chunk_rd, uchar *buf, int max_len);
|
int read_data(binlog_chunk_reader *chunk_rd, uchar *buf, int max_len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ensure_stack(uint32_t length);
|
void push_state(enum oob_states state, uint64_t file_no, uint64_t offset,
|
||||||
bool push_state(enum oob_states state, uint64_t file_no, uint64_t offset,
|
|
||||||
bool is_leftmost);
|
bool is_leftmost);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -474,14 +467,14 @@ innodb_binlog_init(size_t binlog_size, const char *directory)
|
|||||||
uint64_t pages= binlog_size >> srv_page_size_shift;
|
uint64_t pages= binlog_size >> srv_page_size_shift;
|
||||||
if (UNIV_LIKELY(pages > (uint64_t)UINT32_MAX)) {
|
if (UNIV_LIKELY(pages > (uint64_t)UINT32_MAX)) {
|
||||||
pages= UINT32_MAX;
|
pages= UINT32_MAX;
|
||||||
ib::warn() << "Requested max_binlog_size is larger than the maximum " <<
|
sql_print_warning("Requested max_binlog_size is larger than the maximum "
|
||||||
"InnoDB tablespace size, truncated to " <<
|
"InnoDB tablespace size, truncated to %llu",
|
||||||
(pages << srv_page_size_shift) << ".";
|
(pages << srv_page_size_shift));
|
||||||
} else if (pages < 2) { /* Minimum one data page and one index page. */
|
} else if (pages < 2) { /* Minimum one data page and one index page. */
|
||||||
pages= 2;
|
pages= 2;
|
||||||
ib::warn() << "Requested max_binlog_size is smaller than the minimum " <<
|
sql_print_warning("Requested max_binlog_size is smaller than the minimum "
|
||||||
"size supported by InnoDB, truncated to " <<
|
"size supported by InnoDB, truncated to %llu",
|
||||||
(pages << srv_page_size_shift) << ".";
|
(pages << srv_page_size_shift));
|
||||||
}
|
}
|
||||||
innodb_binlog_size_in_pages= (uint32_t)pages;
|
innodb_binlog_size_in_pages= (uint32_t)pages;
|
||||||
|
|
||||||
@@ -489,8 +482,8 @@ innodb_binlog_init(size_t binlog_size, const char *directory)
|
|||||||
directory= ".";
|
directory= ".";
|
||||||
else if (strlen(directory) + BINLOG_NAME_MAX_LEN > OS_FILE_MAX_PATH)
|
else if (strlen(directory) + BINLOG_NAME_MAX_LEN > OS_FILE_MAX_PATH)
|
||||||
{
|
{
|
||||||
ib::error() << "Specified binlog directory path '" << directory <<
|
sql_print_error("Specified binlog directory path '%s' is too long",
|
||||||
"' is too long.";
|
directory);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
innodb_binlog_directory= directory;
|
innodb_binlog_directory= directory;
|
||||||
@@ -582,7 +575,7 @@ find_pos_in_binlog(uint64_t file_no, size_t file_size, byte *page_buf,
|
|||||||
OS_FILE_OPEN, OS_DATA_FILE,
|
OS_FILE_OPEN, OS_DATA_FILE,
|
||||||
srv_read_only_mode, &ret);
|
srv_read_only_mode, &ret);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
ib::warn() << "Unable to open file " << file_name;
|
sql_print_warning("Unable to open file '%s'", file_name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,8 +672,8 @@ innodb_binlog_discover()
|
|||||||
{
|
{
|
||||||
if (my_errno == ENOENT)
|
if (my_errno == ENOENT)
|
||||||
return 0;
|
return 0;
|
||||||
ib::error() << "Could not read the binlog directory '" <<
|
sql_print_error("Could not read the binlog directory '%s', error code %d",
|
||||||
innodb_binlog_directory << "', error code " << my_errno << ".";
|
innodb_binlog_directory, my_errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,9 +708,9 @@ innodb_binlog_discover()
|
|||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
file_no= binlog_files.last_file_no;
|
file_no= binlog_files.last_file_no;
|
||||||
active_binlog_file_no.store(file_no, std::memory_order_release);
|
active_binlog_file_no.store(file_no, std::memory_order_release);
|
||||||
ib::warn() << "Binlog number " << binlog_files.last_file_no <<
|
sql_print_warning("Binlog number %llu could no be opened. Starting a new "
|
||||||
" could no be opened. Starting a new binlog file from number " <<
|
"binlog file from number %llu",
|
||||||
(file_no + 1) << ".";
|
binlog_files.last_file_no,(file_no + 1));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,9 +740,9 @@ innodb_binlog_discover()
|
|||||||
active_binlog_space= space;
|
active_binlog_space= space;
|
||||||
binlog_cur_page_no= page_no;
|
binlog_cur_page_no= page_no;
|
||||||
binlog_cur_page_offset= pos_in_page;
|
binlog_cur_page_offset= pos_in_page;
|
||||||
ib::warn() << "Binlog number " << binlog_files.prev_file_no
|
sql_print_warning("Binlog number %llu could not be opened, starting "
|
||||||
<< " could not be opened, starting from binlog number "
|
"from binlog number %llu instead",
|
||||||
<< file_no << " instead." ;
|
binlog_files.prev_file_no, file_no);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
file_no= binlog_files.prev_file_no;
|
file_no= binlog_files.prev_file_no;
|
||||||
@@ -1161,8 +1154,8 @@ binlog_state_recover()
|
|||||||
}
|
}
|
||||||
if (diff_state_interval == 0 || diff_state_interval % srv_page_size != 0)
|
if (diff_state_interval == 0 || diff_state_interval % srv_page_size != 0)
|
||||||
{
|
{
|
||||||
ib::warn() << "Invalid differential binlog state interval " <<
|
sql_print_warning("Invalid differential binlog state interval %llu found "
|
||||||
diff_state_interval << " found in binlog file, ignoring";
|
"in binlog file, ignoring", diff_state_interval);
|
||||||
current_binlog_state_interval= 0; /* Disable in this binlog file */
|
current_binlog_state_interval= 0; /* Disable in this binlog file */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1437,64 +1430,35 @@ innodb_free_oob(THD *thd, void *engine_data)
|
|||||||
|
|
||||||
|
|
||||||
innodb_binlog_oob_reader::innodb_binlog_oob_reader()
|
innodb_binlog_oob_reader::innodb_binlog_oob_reader()
|
||||||
: stack(init_stack), stack_len(sizeof(init_stack)/sizeof(init_stack[0])),
|
|
||||||
stack_top(0)
|
|
||||||
{
|
{
|
||||||
|
/* Nothing. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
innodb_binlog_oob_reader::~innodb_binlog_oob_reader()
|
innodb_binlog_oob_reader::~innodb_binlog_oob_reader()
|
||||||
{
|
{
|
||||||
if (stack_len > sizeof(init_stack)/sizeof(init_stack[0]))
|
/* Nothing. */
|
||||||
ut_free(stack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
void
|
||||||
innodb_binlog_oob_reader::ensure_stack(uint32_t needed_length)
|
|
||||||
{
|
|
||||||
uint32_t len= stack_len;
|
|
||||||
if (len >= needed_length)
|
|
||||||
return false;
|
|
||||||
do
|
|
||||||
len*= 2;
|
|
||||||
while (len < needed_length);
|
|
||||||
size_t needed= len*sizeof(stack_entry);
|
|
||||||
stack_entry *new_stack= (stack_entry *) ut_malloc(needed, mem_key_binlog);
|
|
||||||
if (!new_stack)
|
|
||||||
{
|
|
||||||
my_error(ER_OUTOFMEMORY, MYF(0), needed);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(new_stack, stack, stack_len*sizeof(stack_entry));
|
|
||||||
stack= new_stack;
|
|
||||||
stack_len= len;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
innodb_binlog_oob_reader::push_state(enum oob_states state, uint64_t file_no,
|
innodb_binlog_oob_reader::push_state(enum oob_states state, uint64_t file_no,
|
||||||
uint64_t offset, bool is_leftmost)
|
uint64_t offset, bool is_leftmost)
|
||||||
{
|
{
|
||||||
uint32_t idx= stack_top;
|
stack_entry new_entry;
|
||||||
if (ensure_stack(idx + 1))
|
new_entry.state= state;
|
||||||
return true;
|
new_entry.file_no= file_no;
|
||||||
stack[idx].state= state;
|
new_entry.offset= offset;
|
||||||
stack[idx].file_no= file_no;
|
new_entry.is_leftmost= is_leftmost;
|
||||||
stack[idx].offset= offset;
|
stack.emplace_back(std::move(new_entry));
|
||||||
stack[idx].is_leftmost= is_leftmost;
|
|
||||||
stack_top= idx + 1;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
void
|
||||||
innodb_binlog_oob_reader::start_traversal(uint64_t file_no, uint64_t offset)
|
innodb_binlog_oob_reader::start_traversal(uint64_t file_no, uint64_t offset)
|
||||||
{
|
{
|
||||||
stack_top= 0;
|
stack.clear();
|
||||||
return push_state(ST_initial, file_no, offset, true);
|
push_state(ST_initial, file_no, offset, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1521,14 +1485,14 @@ innodb_binlog_oob_reader::read_data(binlog_chunk_reader *chunk_rd,
|
|||||||
std::pair<uint64_t, const unsigned char *> v_and_p;
|
std::pair<uint64_t, const unsigned char *> v_and_p;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
if (stack_top <= 0)
|
if (stack.empty())
|
||||||
{
|
{
|
||||||
ut_ad(0 /* Should not call when no more oob data to read. */);
|
ut_ad(0 /* Should not call when no more oob data to read. */);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
again:
|
again:
|
||||||
e= &(stack[stack_top - 1]);
|
e= &(stack[stack.size() - 1]);
|
||||||
switch (e->state)
|
switch (e->state)
|
||||||
{
|
{
|
||||||
case ST_initial:
|
case ST_initial:
|
||||||
@@ -1632,8 +1596,8 @@ again:
|
|||||||
if (chunk_rd->end_of_record())
|
if (chunk_rd->end_of_record())
|
||||||
{
|
{
|
||||||
/* This oob record done, pop the state. */
|
/* This oob record done, pop the state. */
|
||||||
ut_ad(stack_top > 0);
|
ut_ad(!stack.empty());
|
||||||
--stack_top;
|
stack.erase(stack.end() - 1, stack.end());
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
|
|
||||||
@@ -2157,8 +2121,8 @@ innodb_find_binlogs(uint64_t *out_first, uint64_t *out_last)
|
|||||||
MY_DIR *dir= my_dir(innodb_binlog_directory, MYF(0));
|
MY_DIR *dir= my_dir(innodb_binlog_directory, MYF(0));
|
||||||
if (!dir)
|
if (!dir)
|
||||||
{
|
{
|
||||||
ib::error() << "Could not read the binlog directory '" <<
|
sql_print_error("Could not read the binlog directory '%s', error code %d",
|
||||||
innodb_binlog_directory << "', error code " << my_errno << ".";
|
innodb_binlog_directory, my_errno);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2181,12 +2145,12 @@ innodb_find_binlogs(uint64_t *out_first, uint64_t *out_last)
|
|||||||
|
|
||||||
if (num_file_no == 0)
|
if (num_file_no == 0)
|
||||||
{
|
{
|
||||||
ib::error() << "No binlog files found (deleted externally?)";
|
sql_print_error("No binlog files found (deleted externally?)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (num_file_no != last_file_no - first_file_no + 1)
|
if (num_file_no != last_file_no - first_file_no + 1)
|
||||||
{
|
{
|
||||||
ib::error() << "Missing binlog files (deleted externally?)";
|
sql_print_error("Missing binlog files (deleted externally?)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*out_first= first_file_no;
|
*out_first= first_file_no;
|
||||||
@@ -2208,8 +2172,8 @@ innodb_reset_binlogs()
|
|||||||
MY_DIR *dir= my_dir(innodb_binlog_directory, MYF(MY_WME));
|
MY_DIR *dir= my_dir(innodb_binlog_directory, MYF(MY_WME));
|
||||||
if (!dir)
|
if (!dir)
|
||||||
{
|
{
|
||||||
ib::error() << "Could not read the binlog directory '" <<
|
sql_print_error("Could not read the binlog directory '%s', error code %d",
|
||||||
innodb_binlog_directory << "', error code " << my_errno << ".";
|
innodb_binlog_directory, my_errno);
|
||||||
err= true;
|
err= true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -19,6 +19,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#pragma once
|
#pragma once
|
||||||
/* A normally small vector, inspired by llvm::SmallVector */
|
/* A normally small vector, inspired by llvm::SmallVector */
|
||||||
#include "my_global.h"
|
#include "my_global.h"
|
||||||
|
#include "my_valgrind.h"
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ of the multiplication result:
|
|||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
__forceinline unsigned int nlz (ulonglong x)
|
__forceinline unsigned int nlz (unsigned long long x)
|
||||||
{
|
{
|
||||||
#if defined(_M_IX86) || defined(_M_X64)
|
#if defined(_M_IX86) || defined(_M_X64)
|
||||||
unsigned long n;
|
unsigned long n;
|
||||||
@@ -67,7 +67,7 @@ __forceinline unsigned int nlz (ulonglong x)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inline unsigned int nlz (ulonglong x)
|
inline unsigned int nlz (unsigned long long x)
|
||||||
{
|
{
|
||||||
static unsigned char table [48] = {
|
static unsigned char table [48] = {
|
||||||
32, 6, 5, 0, 4, 12, 0, 20,
|
32, 6, 5, 0, 4, 12, 0, 20,
|
||||||
|
Reference in New Issue
Block a user