mirror of https://github.com/tstack/lnav
Some more sequence matching stuff.
parent
e3d2d41aba
commit
44e8abc593
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
#ifndef __byte_array_hh
|
||||||
|
#define __byte_array_hh
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
template<size_t BYTE_COUNT>
|
||||||
|
struct byte_array {
|
||||||
|
byte_array() { };
|
||||||
|
|
||||||
|
byte_array(const byte_array &other) {
|
||||||
|
memcpy(this->ba_data, other.ba_data, BYTE_COUNT);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator<(const byte_array &other) const {
|
||||||
|
return memcmp(this->ba_data, other.ba_data, BYTE_COUNT) < 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned char ba_data[BYTE_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
#include "sequence_matcher.hh"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
sequence_matcher::sequence_matcher(field_col_t &example)
|
||||||
|
{
|
||||||
|
for (field_col_t::iterator col_iter = example.begin();
|
||||||
|
col_iter != example.end();
|
||||||
|
++col_iter) {
|
||||||
|
std::string first_value;
|
||||||
|
field sf;
|
||||||
|
|
||||||
|
sf.sf_value = *col_iter;
|
||||||
|
for (field_row_t::iterator row_iter = (*col_iter).begin();
|
||||||
|
row_iter != (*col_iter).end();
|
||||||
|
++row_iter) {
|
||||||
|
if (row_iter == (*col_iter).begin()) {
|
||||||
|
first_value = *row_iter;
|
||||||
|
}
|
||||||
|
else if (first_value != *row_iter) {
|
||||||
|
sf.sf_type = FT_CONSTANT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sf.sf_type == FT_VARIABLE)
|
||||||
|
sf.sf_value.clear();
|
||||||
|
this->sm_fields.push_back(sf);
|
||||||
|
}
|
||||||
|
this->sm_count = example.front().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sequence_matcher::identity(const std::vector<string> &values, id_t &id_out)
|
||||||
|
{
|
||||||
|
SHA_CTX context;
|
||||||
|
int lpc = 0;
|
||||||
|
|
||||||
|
SHA_Init(&context);
|
||||||
|
for (std::list<field>::iterator iter = sm_fields.begin();
|
||||||
|
iter != sm_fields.end();
|
||||||
|
++iter, lpc++) {
|
||||||
|
if (iter->sf_type == FT_VARIABLE) {
|
||||||
|
SHA_Update(&context,
|
||||||
|
values[lpc].c_str(),
|
||||||
|
values[lpc].length() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SHA_Final(id_out.ba_data, &context);
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
|
||||||
|
#ifndef __sequence_matcher_hh
|
||||||
|
#define __sequence_matcher_hh
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "byte_array.hh"
|
||||||
|
|
||||||
|
class sequence_matcher {
|
||||||
|
public:
|
||||||
|
typedef std::vector<std::string> field_row_t;
|
||||||
|
typedef std::list<field_row_t> field_col_t;
|
||||||
|
|
||||||
|
typedef byte_array<20> id_t;
|
||||||
|
|
||||||
|
enum field_type_t {
|
||||||
|
FT_VARIABLE,
|
||||||
|
FT_CONSTANT,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct field {
|
||||||
|
|
||||||
|
public:
|
||||||
|
field() : sf_type(FT_VARIABLE) { };
|
||||||
|
|
||||||
|
field_type_t sf_type;
|
||||||
|
field_row_t sf_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
sequence_matcher(field_col_t &example);
|
||||||
|
|
||||||
|
void identity(const std::vector<std::string> &values, id_t &id_out);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool match(const std::vector<std::string> &values,
|
||||||
|
std::vector<T> &state,
|
||||||
|
T index) {
|
||||||
|
bool index_match = true;
|
||||||
|
int lpc = 0;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
for (std::list<field>::iterator iter = this->sm_fields.begin();
|
||||||
|
iter != this->sm_fields.end();
|
||||||
|
++iter, lpc++) {
|
||||||
|
if (iter->sf_type != sequence_matcher::FT_CONSTANT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter->sf_value[state.size()] != values[lpc]) {
|
||||||
|
if (state.size() > 0) {
|
||||||
|
state.clear();
|
||||||
|
lpc = 0;
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
index_match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index_match) {
|
||||||
|
state.push_back(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (this->sm_count == state.size());
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
int sm_count;
|
||||||
|
std::list<field> sm_fields;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
#ifndef __sequence_sink_hh
|
||||||
|
#define __sequence_sink_hh
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "bookmarks.hh"
|
||||||
|
#include "grep_proc.hh"
|
||||||
|
#include "sequence_matcher.hh"
|
||||||
|
|
||||||
|
class sequence_sink : public grep_proc_sink {
|
||||||
|
public:
|
||||||
|
sequence_sink(sequence_matcher &sm, bookmark_vector &bv) :
|
||||||
|
ss_matcher(sm),
|
||||||
|
ss_bookmarks(bv) {
|
||||||
|
};
|
||||||
|
|
||||||
|
void grep_match(grep_proc &gp,
|
||||||
|
grep_line_t line,
|
||||||
|
int start,
|
||||||
|
int end) {
|
||||||
|
this->ss_line_values.clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
void grep_capture(grep_proc &gp,
|
||||||
|
grep_line_t line,
|
||||||
|
int start,
|
||||||
|
int end,
|
||||||
|
char *capture) {
|
||||||
|
if (start == -1)
|
||||||
|
this->ss_line_values.push_back("");
|
||||||
|
else
|
||||||
|
this->ss_line_values.push_back(std::string(capture));
|
||||||
|
};
|
||||||
|
|
||||||
|
void grep_match_end(grep_proc &gp, grep_line_t line) {
|
||||||
|
sequence_matcher::id_t line_id;
|
||||||
|
|
||||||
|
this->ss_matcher.identity(this->ss_line_values, line_id);
|
||||||
|
|
||||||
|
std::vector<grep_line_t> &line_state = this->ss_state[line_id];
|
||||||
|
if (this->ss_matcher.match(this->ss_line_values,
|
||||||
|
line_state,
|
||||||
|
line)) {
|
||||||
|
std::vector<grep_line_t>::iterator iter;
|
||||||
|
|
||||||
|
for (iter = line_state.begin();
|
||||||
|
iter != line_state.end();
|
||||||
|
++iter) {
|
||||||
|
this->ss_bookmarks.insert_once(vis_line_t(*iter));
|
||||||
|
}
|
||||||
|
line_state.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
sequence_matcher &ss_matcher;
|
||||||
|
bookmark_vector &ss_bookmarks;
|
||||||
|
std::vector<std::string> ss_line_values;
|
||||||
|
std::map< sequence_matcher::id_t, std::vector<grep_line_t> > ss_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,3 @@
|
|||||||
|
Nov 3 09:23:38 veridian foo[7998]: eth0 is up
|
||||||
|
Nov 3 09:23:38 veridian foo[16442]: eth1 is up
|
||||||
|
Nov 3 09:23:38 veridian foo[7999]: eth0 is down
|
Loading…
Reference in New Issue