From ccf29b3bac18b064cc1b9b201281c91cc86713a6 Mon Sep 17 00:00:00 2001 From: Timothy Stack Date: Sun, 28 Sep 2014 22:36:07 -0700 Subject: [PATCH] [coverity] some cleanup and add the chunky_index --- CMakeLists.txt | 1 + src/CMakeLists.txt | 1 + src/ansi_scrubber.cc | 12 +- src/auto_fd.hh | 4 +- src/chunky_index.hh | 229 ++++++++++++++++++++++++++++++++++ src/collation-functions.cc | 2 +- src/concise_index.hh | 12 +- src/data_parser.hh | 14 +-- src/data_scanner.hh | 4 +- src/fs-extension-functions.cc | 11 +- src/grep_proc.cc | 3 +- src/grep_proc.hh | 2 + src/line_buffer.cc | 2 +- src/lnav.cc | 2 +- src/log_format.cc | 9 +- src/log_vtab_impl.cc | 4 +- src/logfile_sub_source.hh | 14 --- src/piper_proc.cc | 15 +-- src/piper_proc.hh | 3 +- src/readline_curses.cc | 2 +- test/CMakeLists.txt | 4 + test/Makefile.am | 5 + test/Makefile.in | 56 ++++++--- test/test_chunky_index.cc | 97 ++++++++++++++ 24 files changed, 426 insertions(+), 82 deletions(-) create mode 100644 src/chunky_index.hh create mode 100644 test/CMakeLists.txt create mode 100644 test/test_chunky_index.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index d8349e3d..4a54309b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,3 +2,4 @@ cmake_minimum_required (VERSION 2.6) project (lnav) add_subdirectory(src) +add_subdirectory(test) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47991923..be1fd3c0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -68,6 +68,7 @@ set(diag_STAT_SRCS auto_pid.hh bottom_status_source.hh byte_array.hh + chunky_index.hh concise_index.hh column_namer.hh format-text-files.hh diff --git a/src/ansi_scrubber.cc b/src/ansi_scrubber.cc index 305d016b..66fbe473 100644 --- a/src/ansi_scrubber.cc +++ b/src/ansi_scrubber.cc @@ -61,12 +61,12 @@ void scrub_ansi_string(std::string &str, string_attrs_t &sa) int attrs = 0; int bg = 0; int fg = 0; - int lpc; + unsigned long lpc; switch (pi.get_substr_start(&caps[2])[0]) { case 'm': - for (lpc = caps[1].c_begin; - lpc != (int)string::npos && lpc < caps[1].c_end; ) { + for (lpc = (unsigned long) caps[1].c_begin; + lpc != string::npos && lpc < caps[1].c_end; ) { int ansi_code = 0; if (sscanf(&(str[lpc]), "%d", &ansi_code) == 1) { @@ -111,11 +111,11 @@ void scrub_ansi_string(std::string &str, string_attrs_t &sa) case 'C': { - int spaces = 0; + unsigned int spaces = 0; - if (sscanf(&(str[caps[1].c_begin]), "%d", &spaces) == 1 && + if (sscanf(&(str[caps[1].c_begin]), "%u", &spaces) == 1 && spaces > 0) { - str.insert(caps[0].c_end, spaces, ' '); + str.insert((unsigned long) caps[0].c_end, spaces, ' '); } } break; diff --git a/src/auto_fd.hh b/src/auto_fd.hh index 88f33161..b44f3353 100644 --- a/src/auto_fd.hh +++ b/src/auto_fd.hh @@ -204,8 +204,6 @@ private: class auto_pipe { public: - static const int STDIO_FD_COUNT = 3; - auto_pipe(int child_fd = -1, int child_flags = O_RDONLY) : ap_child_flags(child_flags), ap_child_fd(child_fd) { @@ -238,7 +236,7 @@ public: }; void after_fork(pid_t child_pid) { - int new_fd = -1; + int new_fd; switch (child_pid) { case -1: diff --git a/src/chunky_index.hh b/src/chunky_index.hh new file mode 100644 index 00000000..0d4ceccf --- /dev/null +++ b/src/chunky_index.hh @@ -0,0 +1,229 @@ +/** +* Copyright (c) 2014, Timothy Stack +* +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* * Redistributions of source code must retain the above copyright notice, this +* list of conditions and the following disclaimer. +* * 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. +* * Neither the name of Timothy Stack nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* @file chunky_index.hh +*/ + +#ifndef __chunky_index_hh +#define __chunky_index_hh + +#include + +#include +#include + +#include "lnav_log.hh" + +template +class chunky_index { + +public: + chunky_index() : ci_generation(0), ci_merge_chunk(NULL), ci_size(0) { + }; + + ~chunky_index() { + this->clear(); + }; + + size_t size() const { + return this->ci_size; + }; + + size_t chunk_count() const { + return this->ci_completed_chunks.size(); + }; + + T& operator[](size_t index) { + size_t chunk_index = index / CHUNK_SIZE; + assert(chunk_index < this->chunk_count()); + struct chunk *target_chunk = this->ci_completed_chunks[chunk_index]; + return target_chunk->c_body[index % CHUNK_SIZE]; + }; + + void clear() { + while (!this->ci_completed_chunks.empty()) { + delete this->ci_completed_chunks.back(); + this->ci_completed_chunks.pop_back(); + } + while (!this->ci_pending_chunks.empty()) { + delete this->ci_pending_chunks.front(); + this->ci_pending_chunks.pop_front(); + } + if (this->ci_merge_chunk != NULL) { + delete this->ci_merge_chunk; + this->ci_merge_chunk = NULL; + } + this->ci_size = 0; + }; + + void reset() { + for (size_t lpc = 0; lpc < this->ci_completed_chunks.size(); lpc++) { + this->ci_pending_chunks.push_back(this->ci_completed_chunks[lpc]); + } + this->ci_completed_chunks.clear(); + this->ci_generation += 1; + }; + + template + void merge_value(const T &val, Comparator comparator) { + this->merge_up_to(&val, comparator); + this->ci_merge_chunk->push_back(val); + + this->ci_size += 1; + }; + + void merge_value(const T &val) { + this->merge_value(val, less_comparator()); + }; + + void finish() { + this->merge_up_to(NULL, null_comparator()); + if (this->ci_merge_chunk != NULL) { + if (this->ci_merge_chunk->empty()) { + delete this->ci_merge_chunk; + this->ci_merge_chunk = NULL; + } + else { + this->ci_completed_chunks.push_back(this->ci_merge_chunk); + this->ci_merge_chunk = NULL; + } + } + }; + +private: + void skip_chunks(const T *val) { + while (!this->ci_pending_chunks.empty() && this->ci_pending_chunks.front()->skippable(val)) { + struct chunk *skipped_chunk = this->ci_pending_chunks.front(); + this->ci_pending_chunks.pop_front(); + skipped_chunk->c_consumed = 0; + skipped_chunk->c_generation = this->ci_generation; + this->ci_completed_chunks.push_back(skipped_chunk); + } + }; + + struct null_comparator { + int operator()(const T &val, const T &other) const { + return 0; + }; + }; + + struct less_comparator { + int operator()(const T &val, const T &other) const { + if (val < other) { + return -1; + } + else if (other < val) { + return 1; + } + else { + return 0; + } + }; + }; + + template + void merge_up_to(const T *val, Comparator comparator) { + this->skip_chunks(val); + + do { + if (this->ci_merge_chunk != NULL && this->ci_merge_chunk->full()) { + this->ci_completed_chunks.push_back(this->ci_merge_chunk); + this->ci_merge_chunk = NULL; + } + if (this->ci_merge_chunk == NULL) { + this->ci_merge_chunk = new chunk(this->ci_generation); + } + + if (!this->ci_pending_chunks.empty()) { + struct chunk *next_chunk = this->ci_pending_chunks.front(); + while (((val == NULL) || (comparator(next_chunk->front(), *val) < 0)) && + !this->ci_merge_chunk->full()) { + this->ci_merge_chunk->push_back(next_chunk->consume()); + if (next_chunk->empty()) { + this->ci_pending_chunks.pop_front(); + delete next_chunk; + if (!this->ci_pending_chunks.empty()) { + next_chunk = this->ci_pending_chunks.front(); + } else { + break; + } + } + } + } + } while (this->ci_merge_chunk->full()); + }; + + struct chunk { + chunk(unsigned long gen) : c_generation(gen), c_consumed(0), c_used(0) { }; + + bool empty() const { + return this->c_consumed == this->c_used; + }; + + bool full() const { + return this->c_used == CHUNK_SIZE; + }; + + bool skippable(const T *val) const { + return this->c_consumed == 0 && this->full() && ( + val == NULL || (this->back() <= *val)); + }; + + const T &front() const { + return this->c_body[this->c_consumed]; + }; + + const T &consume() { + this->c_consumed += 1; + return this->c_body[this->c_consumed - 1]; + }; + + const T &back() const { + return this->c_body[this->c_used - 1]; + }; + + void push_back(const T &val) { + this->c_body[this->c_used] = val; + this->c_used += 1; + }; + + unsigned long c_generation; + T c_body[CHUNK_SIZE]; + size_t c_consumed; + size_t c_used; + }; + + unsigned long ci_generation; + std::vector ci_completed_chunks; + struct chunk *ci_merge_chunk; + std::list ci_pending_chunks; + + size_t ci_size; +}; + +#endif diff --git a/src/collation-functions.cc b/src/collation-functions.cc index a3346a1b..093073c6 100644 --- a/src/collation-functions.cc +++ b/src/collation-functions.cc @@ -53,7 +53,7 @@ static int try_inet_pton(int p_len, const char *p, char *n) { static int family[] = { AF_INET6, AF_INET, AF_MAX }; - char buf[MAX_ADDR_LEN]; + char buf[MAX_ADDR_LEN + 1]; int retval = AF_MAX; strncpy(buf, p, p_len); diff --git a/src/concise_index.hh b/src/concise_index.hh index 91d9bcd5..b3a80df0 100644 --- a/src/concise_index.hh +++ b/src/concise_index.hh @@ -36,7 +36,7 @@ #include -#include +#include "lnav_log.hh" class concise_index { @@ -112,7 +112,7 @@ public: return true; } - for (int lpc = len; lpc < BITS_PER_WORD; lpc++) { + for (uint64_t lpc = len; lpc < BITS_PER_WORD; lpc++) { uint64_t mask = 1ULL << (len - 1); uint64_t bit_to_set_or_clear = (1ULL << lpc); @@ -125,7 +125,7 @@ public: if ((v == 0ULL || v == ~0ULL) && (this->is_rle(lit_or_rle_word) || this->ci_literal_size == 0)) { - bool bv = v; + bool bv = (bool) v; if (this->is_rle(lit_or_rle_word)) { if (this->get_rle_value(lit_or_rle_word) == bv && @@ -267,7 +267,7 @@ public: return this->i_parent->get_rle_value(word); } - return word & this->i_parent->bit_in_word(this->i_bit_index); + return (bool) (word & this->i_parent->bit_in_word(this->i_bit_index)); }; uint64_t get_word(size_t &valid_bits_out) const { @@ -367,11 +367,11 @@ public: }; bool get_rle_value(uint64_t v) const { - return (v & VAL_MASK); + return (bool) (v & VAL_MASK); }; int pos_index(uint64_t v) const { - return (v & POS_MASK) >> (64 - 6 - 1); + return (int) ((v & POS_MASK) >> (64 - 6 - 1)); }; uint64_t run_length(uint64_t v) const { diff --git a/src/data_parser.hh b/src/data_parser.hh index a3b12769..85e77df9 100644 --- a/src/data_parser.hh +++ b/src/data_parser.hh @@ -640,11 +640,11 @@ private: if (pairs_out.size() == 1) { element &pair = pairs_out.front(); - element &value = pair.e_sub_elements->back(); + element &evalue = pair.e_sub_elements->back(); - if (value.e_token == DNT_VALUE && - value.e_sub_elements != NULL && - value.e_sub_elements->size() > 1) { + if (evalue.e_token == DNT_VALUE && + evalue.e_sub_elements != NULL && + evalue.e_sub_elements->size() > 1) { element_list_t::iterator next_sub; next_sub = pair.e_sub_elements->begin(); @@ -655,9 +655,9 @@ private: next_sub); free_row.clear(); free_row.SPLICE(free_row.begin(), - *value.e_sub_elements, - value.e_sub_elements->begin(), - value.e_sub_elements->end()); + *evalue.e_sub_elements, + evalue.e_sub_elements->begin(), + evalue.e_sub_elements->end()); pairs_out.clear(); context.Init(0, 0); } diff --git a/src/data_scanner.hh b/src/data_scanner.hh index e561a131..63a14bcb 100644 --- a/src/data_scanner.hh +++ b/src/data_scanner.hh @@ -106,7 +106,7 @@ class data_scanner { public: static const char *token2name(data_token_t token); - data_scanner(const std::string &line, size_t off = 0, size_t len = -1) + data_scanner(const std::string &line, size_t off = 0, size_t len = (size_t) -1) : ds_line(line), ds_pcre_input(ds_line.c_str(), off, len) { @@ -115,7 +115,7 @@ public: } }; - data_scanner(shared_buffer_ref &line, size_t off = 0, size_t len = -1) + data_scanner(shared_buffer_ref &line, size_t off = 0, size_t len = (size_t) -1) : ds_sbr(line), ds_pcre_input(line.get_data(), off, len) { if (line.length() > 0 && line.get_data()[line.length() - 1] == '.') { diff --git a/src/fs-extension-functions.cc b/src/fs-extension-functions.cc index e4c952c6..08ff20e1 100644 --- a/src/fs-extension-functions.cc +++ b/src/fs-extension-functions.cc @@ -37,6 +37,7 @@ #include #include +#include #include "sqlite3.h" @@ -60,17 +61,17 @@ static void sql_basename(sqlite3_context *context, return; } - for (int lpc = strlen(path_in) - 1; lpc >= 0; lpc--) { + for (ssize_t lpc = strlen(path_in) - 1; lpc >= 0; lpc--) { if (path_in[lpc] == '/' || path_in[lpc] == '\\') { if (text_end != -1) { sqlite3_result_text(context, - &path_in[lpc + 1], text_end - lpc - 1, + &path_in[lpc + 1], (int) (text_end - lpc - 1), SQLITE_TRANSIENT); return; } } else if (text_end == -1) { - text_end = lpc + 1; + text_end = (int) (lpc + 1); } } @@ -88,7 +89,7 @@ static void sql_dirname(sqlite3_context *context, int argc, sqlite3_value **argv) { const char *path_in; - int text_end; + ssize_t text_end; if (sqlite3_value_type(argv[0]) == SQLITE_NULL) { sqlite3_result_null(context); @@ -106,7 +107,7 @@ static void sql_dirname(sqlite3_context *context, while (text_end >= 0) { if (path_in[text_end] == '/' || path_in[text_end] == '\\') { sqlite3_result_text(context, - path_in, text_end == 0 ? 1 : text_end, + path_in, (int) (text_end == 0 ? 1 : text_end), SQLITE_TRANSIENT); return; } diff --git a/src/grep_proc.cc b/src/grep_proc.cc index e25842d0..11abfd11 100644 --- a/src/grep_proc.cc +++ b/src/grep_proc.cc @@ -39,6 +39,7 @@ #include #include #include +#include #include "lnav_log.hh" #include "grep_proc.hh" @@ -328,7 +329,7 @@ void grep_proc::check_fd_set(fd_set &ready_fds) if (this->gp_err_pipe != -1 && FD_ISSET(this->gp_err_pipe, &ready_fds)) { char buffer[1024 + 1]; - int rc; + ssize_t rc; rc = read(this->gp_err_pipe, buffer, sizeof(buffer) - 1); if (rc > 0) { diff --git a/src/grep_proc.hh b/src/grep_proc.hh index a733f26d..e914993b 100644 --- a/src/grep_proc.hh +++ b/src/grep_proc.hh @@ -32,6 +32,8 @@ #ifndef __grep_proc_hh #define __grep_proc_hh +#include "config.h" + #include #include #include diff --git a/src/line_buffer.cc b/src/line_buffer.cc index 9184ea31..99285504 100644 --- a/src/line_buffer.cc +++ b/src/line_buffer.cc @@ -108,7 +108,7 @@ private: unlink(lockname); }; - int lh_fd; + auto_fd lh_fd; }; /* XXX END */ diff --git a/src/lnav.cc b/src/lnav.cc index d4c923dd..a0e06365 100644 --- a/src/lnav.cc +++ b/src/lnav.cc @@ -4409,7 +4409,7 @@ int main(int argc, char *argv[]) } } - if (lnav_data.ld_file_names.empty() && !lnav_data.ld_flags & LNF_HELP) { + if (lnav_data.ld_file_names.empty() && !(lnav_data.ld_flags & LNF_HELP)) { fprintf(stderr, "error: no log files given/found.\n"); retval = EXIT_FAILURE; } diff --git a/src/log_format.cc b/src/log_format.cc index 68b1c14f..41972d35 100644 --- a/src/log_format.cc +++ b/src/log_format.cc @@ -243,9 +243,10 @@ const char *log_format::log_scanf(const char *line, { int curr_fmt = -1; const char * retval = NULL; + bool done = false; va_list args; - while (next_format(fmt, curr_fmt, this->lf_fmt_lock)) { + while (!done && next_format(fmt, curr_fmt, this->lf_fmt_lock)) { va_start(args, tv_out); int matches; @@ -254,10 +255,8 @@ const char *log_format::log_scanf(const char *line, matches = vsscanf(line, fmt[curr_fmt], args); if (matches < expected_matches) { retval = NULL; - continue; } - - if (time_dest[0] == '\0') { + else if (time_dest[0] == '\0') { retval = NULL; } else { @@ -265,7 +264,7 @@ const char *log_format::log_scanf(const char *line, if (retval) { this->lf_fmt_lock = curr_fmt; - break; + done = true; } } diff --git a/src/log_vtab_impl.cc b/src/log_vtab_impl.cc index ae547ce4..1380f10a 100644 --- a/src/log_vtab_impl.cc +++ b/src/log_vtab_impl.cc @@ -182,7 +182,7 @@ static int vt_open(sqlite3_vtab *p_svt, sqlite3_vtab_cursor **pp_cursor) p_vt->base.zErrMsg = NULL; - vtab_cursor *p_cur = (vtab_cursor *)new vtab_cursor(); + vtab_cursor *p_cur = new vtab_cursor(); *pp_cursor = (sqlite3_vtab_cursor *)p_cur; @@ -192,7 +192,7 @@ static int vt_open(sqlite3_vtab *p_svt, sqlite3_vtab_cursor **pp_cursor) p_cur->log_cursor.lc_sub_index = 0; vt_next((sqlite3_vtab_cursor *)p_cur); - return p_cur ? SQLITE_OK : SQLITE_NOMEM; + return SQLITE_OK; } static int vt_close(sqlite3_vtab_cursor *cur) diff --git a/src/logfile_sub_source.hh b/src/logfile_sub_source.hh index a1d7361f..1e98329f 100644 --- a/src/logfile_sub_source.hh +++ b/src/logfile_sub_source.hh @@ -342,20 +342,6 @@ public: : ld_file(lf), ld_lines_indexed(0) { }; - bool operator<(const logfile_data &rhs) - { - if (this->ld_file == rhs.ld_file) { - return false; - } - if (this->ld_file == NULL) { - return true; - } - if (this->ld_file != NULL) { - return true; - } - return (*this->ld_file) < (*rhs.ld_file); - }; - void clear(void) { this->ld_file = NULL; diff --git a/src/piper_proc.cc b/src/piper_proc.cc index 7a69bf9b..f8a585f1 100644 --- a/src/piper_proc.cc +++ b/src/piper_proc.cc @@ -43,6 +43,7 @@ #include #include #include +#include #include "lnav_log.hh" #include "piper_proc.hh" @@ -52,7 +53,7 @@ using namespace std; static const char *STDIN_EOF_MSG = "---- END-OF-STDIN ----"; -static int write_timestamp(int fd, off_t woff) +static ssize_t write_timestamp(int fd, off_t woff) { char time_str[64]; struct timeval tv; @@ -79,15 +80,15 @@ piper_proc::piper_proc(int pipefd, bool timestamp, const char *filename) } } else { - char piper_tmpname[PATH_MAX]; + char piper_tmpname[PATH_MAX]; const char *tmpdir; if ((tmpdir = getenv("TMPDIR")) == NULL) { tmpdir = _PATH_VARTMP; } snprintf(piper_tmpname, sizeof(piper_tmpname), - "%s/lnav.piper.XXXXXX", - tmpdir); + "%s/lnav.piper.XXXXXX", + tmpdir); if ((this->pp_fd = mkstemp(piper_tmpname)) == -1) { throw error(errno); } @@ -95,7 +96,7 @@ piper_proc::piper_proc(int pipefd, bool timestamp, const char *filename) unlink(piper_tmpname); } - fcntl(this->pp_fd, F_SETFD, FD_CLOEXEC); + fcntl(this->pp_fd.get(), F_SETFD, FD_CLOEXEC); this->pp_child = fork(); switch (this->pp_child) { @@ -123,7 +124,7 @@ piper_proc::piper_proc(int pipefd, bool timestamp, const char *filename) select(lb.get_fd() + 1, &rready, NULL, NULL, NULL); last_off = off; while (lb.read_line(off, lv, true)) { - int wrc; + ssize_t wrc; last_woff = woff; if (timestamp) { @@ -154,7 +155,7 @@ piper_proc::piper_proc(int pipefd, bool timestamp, const char *filename) } while (lb.get_file_size() == (ssize_t)-1); if (timestamp) { - int wrc; + ssize_t wrc; wrc = write_timestamp(this->pp_fd, woff); if (wrc == -1) { diff --git a/src/piper_proc.hh b/src/piper_proc.hh index b87eff00..fe94eafe 100644 --- a/src/piper_proc.hh +++ b/src/piper_proc.hh @@ -34,6 +34,7 @@ #include #include +#include "auto_fd.hh" /** * Creates a subprocess that reads data from a pipe and writes it to a file so @@ -76,7 +77,7 @@ public: private: /** A file descriptor that refers to the temporary file. */ - int pp_fd; + auto_fd pp_fd; /** The child process' pid. */ pid_t pp_child; diff --git a/src/readline_curses.cc b/src/readline_curses.cc index 0e4da465..759bcd4e 100644 --- a/src/readline_curses.cc +++ b/src/readline_curses.cc @@ -339,7 +339,7 @@ readline_curses::readline_curses() stifle_history(HISTORY_SIZE); for (int lpc = 0; RL_INIT[lpc]; lpc++) { - strcpy(buffer, RL_INIT[lpc]); + snprintf(buffer, sizeof(buffer), "%s", RL_INIT[lpc]); rl_parse_and_bind(buffer); /* NOTE: buffer is modified */ } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..f0910c01 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,4 @@ + +include_directories(../../lbuild/src ../src/) + +add_executable(test_chunky_index test_chunky_index.cc) diff --git a/test/Makefile.am b/test/Makefile.am index 252be8fc..bc3516fd 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -33,6 +33,7 @@ check_PROGRAMS = \ test_auto_fd \ test_auto_mem \ test_bookmarks \ + test_chunky_index \ test_concise \ test_date_time_scanner \ test_grep_proc2 \ @@ -62,6 +63,9 @@ test_auto_mem_SOURCES = test_auto_mem.cc test_bookmarks_SOURCES = test_bookmarks.cc test_bookmarks_LDADD = ../src/libdiag.a +test_chunky_index_SOURCES = test_chunky_index.cc +test_chunky_index_LDADD = ../src/libdiag.a + test_date_time_scanner_SOURCES = test_date_time_scanner.cc test_date_time_scanner_LDADD = ../src/libdiag.a $(SQLITE3_LIBS) @@ -235,6 +239,7 @@ TESTS = \ test_auto_fd \ test_auto_mem \ test_bookmarks \ + test_chunky_index \ test_date_time_scanner \ test_cmds.sh \ test_concise \ diff --git a/test/Makefile.in b/test/Makefile.in index b35a112a..238c7937 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -88,16 +88,16 @@ check_PROGRAMS = drive_data_scanner$(EXEEXT) \ drive_vt52_curses$(EXEEXT) drive_readline_curses$(EXEEXT) \ slicer$(EXEEXT) scripty$(EXEEXT) test_ansi_scrubber$(EXEEXT) \ test_auto_fd$(EXEEXT) test_auto_mem$(EXEEXT) \ - test_bookmarks$(EXEEXT) test_concise$(EXEEXT) \ - test_date_time_scanner$(EXEEXT) test_grep_proc2$(EXEEXT) \ - test_hist_source$(EXEEXT) test_json_ptr$(EXEEXT) \ - test_line_buffer2$(EXEEXT) test_log_accel$(EXEEXT) \ - test_pcrepp$(EXEEXT) test_top_status$(EXEEXT) \ - test_yajlpp$(EXEEXT) + test_bookmarks$(EXEEXT) test_chunky_index$(EXEEXT) \ + test_concise$(EXEEXT) test_date_time_scanner$(EXEEXT) \ + test_grep_proc2$(EXEEXT) test_hist_source$(EXEEXT) \ + test_json_ptr$(EXEEXT) test_line_buffer2$(EXEEXT) \ + test_log_accel$(EXEEXT) test_pcrepp$(EXEEXT) \ + test_top_status$(EXEEXT) test_yajlpp$(EXEEXT) TESTS = test_ansi_scrubber$(EXEEXT) test_auto_fd$(EXEEXT) \ test_auto_mem$(EXEEXT) test_bookmarks$(EXEEXT) \ - test_date_time_scanner$(EXEEXT) test_cmds.sh \ - test_concise$(EXEEXT) test_line_buffer2$(EXEEXT) \ + test_chunky_index$(EXEEXT) test_date_time_scanner$(EXEEXT) \ + test_cmds.sh test_concise$(EXEEXT) test_line_buffer2$(EXEEXT) \ test_line_buffer.sh test_listview.sh test_mvwattrline.sh \ test_grep_proc.sh test_grep_proc2$(EXEEXT) \ test_hist_source$(EXEEXT) test_json_format.sh test_json_op.sh \ @@ -197,6 +197,9 @@ test_auto_mem_DEPENDENCIES = am_test_bookmarks_OBJECTS = test_bookmarks.$(OBJEXT) test_bookmarks_OBJECTS = $(am_test_bookmarks_OBJECTS) test_bookmarks_DEPENDENCIES = ../src/libdiag.a +am_test_chunky_index_OBJECTS = test_chunky_index.$(OBJEXT) +test_chunky_index_OBJECTS = $(am_test_chunky_index_OBJECTS) +test_chunky_index_DEPENDENCIES = ../src/libdiag.a am_test_concise_OBJECTS = test_concise.$(OBJEXT) test_concise_OBJECTS = $(am_test_concise_OBJECTS) test_concise_DEPENDENCIES = ../src/libdiag.a @@ -268,12 +271,12 @@ SOURCES = $(drive_data_scanner_SOURCES) $(drive_grep_proc_SOURCES) \ $(drive_vt52_curses_SOURCES) $(scripty_SOURCES) \ $(slicer_SOURCES) $(test_ansi_scrubber_SOURCES) \ $(test_auto_fd_SOURCES) $(test_auto_mem_SOURCES) \ - $(test_bookmarks_SOURCES) $(test_concise_SOURCES) \ - $(test_date_time_scanner_SOURCES) $(test_grep_proc2_SOURCES) \ - $(test_hist_source_SOURCES) $(test_json_ptr_SOURCES) \ - $(test_line_buffer2_SOURCES) $(test_log_accel_SOURCES) \ - $(test_pcrepp_SOURCES) $(test_top_status_SOURCES) \ - $(test_yajlpp_SOURCES) + $(test_bookmarks_SOURCES) $(test_chunky_index_SOURCES) \ + $(test_concise_SOURCES) $(test_date_time_scanner_SOURCES) \ + $(test_grep_proc2_SOURCES) $(test_hist_source_SOURCES) \ + $(test_json_ptr_SOURCES) $(test_line_buffer2_SOURCES) \ + $(test_log_accel_SOURCES) $(test_pcrepp_SOURCES) \ + $(test_top_status_SOURCES) $(test_yajlpp_SOURCES) DIST_SOURCES = $(drive_data_scanner_SOURCES) \ $(drive_grep_proc_SOURCES) $(drive_json_op_SOURCES) \ $(drive_json_ptr_walk_SOURCES) $(drive_line_buffer_SOURCES) \ @@ -284,11 +287,12 @@ DIST_SOURCES = $(drive_data_scanner_SOURCES) \ $(scripty_SOURCES) $(slicer_SOURCES) \ $(test_ansi_scrubber_SOURCES) $(test_auto_fd_SOURCES) \ $(test_auto_mem_SOURCES) $(test_bookmarks_SOURCES) \ - $(test_concise_SOURCES) $(test_date_time_scanner_SOURCES) \ - $(test_grep_proc2_SOURCES) $(test_hist_source_SOURCES) \ - $(test_json_ptr_SOURCES) $(test_line_buffer2_SOURCES) \ - $(test_log_accel_SOURCES) $(test_pcrepp_SOURCES) \ - $(test_top_status_SOURCES) $(test_yajlpp_SOURCES) + $(test_chunky_index_SOURCES) $(test_concise_SOURCES) \ + $(test_date_time_scanner_SOURCES) $(test_grep_proc2_SOURCES) \ + $(test_hist_source_SOURCES) $(test_json_ptr_SOURCES) \ + $(test_line_buffer2_SOURCES) $(test_log_accel_SOURCES) \ + $(test_pcrepp_SOURCES) $(test_top_status_SOURCES) \ + $(test_yajlpp_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -662,6 +666,8 @@ test_auto_fd_LDADD = ../src/libdiag.a test_auto_mem_SOURCES = test_auto_mem.cc test_bookmarks_SOURCES = test_bookmarks.cc test_bookmarks_LDADD = ../src/libdiag.a +test_chunky_index_SOURCES = test_chunky_index.cc +test_chunky_index_LDADD = ../src/libdiag.a test_date_time_scanner_SOURCES = test_date_time_scanner.cc test_date_time_scanner_LDADD = ../src/libdiag.a $(SQLITE3_LIBS) test_grep_proc2_SOURCES = test_grep_proc2.cc @@ -935,6 +941,10 @@ test_bookmarks$(EXEEXT): $(test_bookmarks_OBJECTS) $(test_bookmarks_DEPENDENCIES @rm -f test_bookmarks$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(test_bookmarks_OBJECTS) $(test_bookmarks_LDADD) $(LIBS) +test_chunky_index$(EXEEXT): $(test_chunky_index_OBJECTS) $(test_chunky_index_DEPENDENCIES) $(EXTRA_test_chunky_index_DEPENDENCIES) + @rm -f test_chunky_index$(EXEEXT) + $(AM_V_CXXLD)$(CXXLINK) $(test_chunky_index_OBJECTS) $(test_chunky_index_LDADD) $(LIBS) + test_concise$(EXEEXT): $(test_concise_OBJECTS) $(test_concise_DEPENDENCIES) $(EXTRA_test_concise_DEPENDENCIES) @rm -f test_concise$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(test_concise_OBJECTS) $(test_concise_LDADD) $(LIBS) @@ -1000,6 +1010,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auto_fd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auto_mem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_bookmarks.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_chunky_index.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_concise.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_date_time_scanner.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_grep_proc2.Po@am__quote@ @@ -1248,6 +1259,13 @@ test_bookmarks.log: test_bookmarks$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +test_chunky_index.log: test_chunky_index$(EXEEXT) + @p='test_chunky_index$(EXEEXT)'; \ + b='test_chunky_index'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) test_date_time_scanner.log: test_date_time_scanner$(EXEEXT) @p='test_date_time_scanner$(EXEEXT)'; \ b='test_date_time_scanner'; \ diff --git a/test/test_chunky_index.cc b/test/test_chunky_index.cc new file mode 100644 index 00000000..2182e276 --- /dev/null +++ b/test/test_chunky_index.cc @@ -0,0 +1,97 @@ + +#include "config.h" + +#include +#include + +#include "chunky_index.hh" +#include "../src/chunky_index.hh" + +int main(int argc, char *argv[]) +{ + int retval = EXIT_SUCCESS; + + { + chunky_index ci; + + ci.reset(); + ci.finish(); + assert(ci.chunk_count() == 0); + } + + { + chunky_index ci; + + ci.reset(); + ci.merge_value(1); + ci.finish(); + ci.reset(); + ci.merge_value(2); + ci.finish(); + + assert(ci.size() == 2); + assert(ci[0] == 1); + assert(ci[1] == 2); + assert(ci.chunk_count() == 1); + + ci.clear(); + assert(ci.size() == 0); + assert(ci.chunk_count() == 0); + } + + { + int expected[] = {0, 10, 11, 20, 30, 40, 50, 60, 70, 80, 90, 100}; + chunky_index ci; + + ci.reset(); + for (int lpc = 0; lpc < 11; lpc++) { + ci.merge_value(lpc * 10); + } + ci.finish(); + ci.reset(); + ci.merge_value(11); + ci.finish(); + for (int lpc = 0; lpc < 12; lpc++) { + assert(expected[lpc] == ci[lpc]); + } + assert(ci.chunk_count() == 3); + } + + { + int expected[] = {0, 10, 20, 30, 40, 50, 51, 60, 70, 80, 90, 100}; + chunky_index ci; + + ci.reset(); + for (int lpc = 0; lpc < 11; lpc++) { + ci.merge_value(lpc * 10); + } + ci.finish(); + ci.reset(); + ci.merge_value(51); + ci.finish(); + for (int lpc = 0; lpc < 12; lpc++) { + assert(expected[lpc] == ci[lpc]); + } + assert(ci.chunk_count() == 3); + } + + { + int expected[] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110}; + chunky_index ci; + + ci.reset(); + for (int lpc = 0; lpc < 11; lpc++) { + ci.merge_value(lpc * 10); + } + ci.finish(); + ci.reset(); + ci.merge_value(110); + ci.finish(); + for (int lpc = 0; lpc < 12; lpc++) { + assert(expected[lpc] == ci[lpc]); + } + assert(ci.chunk_count() == 3); + } + + return retval; +}