Skip to content

Commit

Permalink
prefix row length when printing with gufi_query -u
Browse files Browse the repository at this point in the history
allocate entire row instead of building up
  • Loading branch information
calccrypto committed Feb 5, 2025
1 parent b59e1c9 commit 09b36e7
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 55 deletions.
67 changes: 22 additions & 45 deletions src/gufi_vt.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,45 +205,37 @@ static const size_t TL = sizeof(char) + sizeof(size_t);

/* read TLV rows terminated by newline - this only works because type is in the range [1, 5] */
static int gufi_query_read_row(gufi_vtab_cursor *pCur) {
size_t size = sizeof(int);
char *buf = malloc(size);
static const size_t row_prefix = sizeof(size_t) + sizeof(int);
char *buf = NULL;
char *curr = buf;
ptrdiff_t curr_offset = 0;

size_t *starts = NULL; /* index of where each column starts in buf */
int count = 0; /* number of columns */
size_t row_len = 0;
int count = 0;

// each row is prefixed with a count
if (fread(curr, sizeof(char), sizeof(int), pCur->output) != sizeof(int)) {
/* row length */
if (fread(&row_len, sizeof(char), sizeof(row_len), pCur->output) != sizeof(row_len)) {
if (ferror(pCur->output)) {
fprintf(stderr, "Error: Could not read row length\n");
}
goto error;
}

count = * (int *) curr;
starts = malloc(count * sizeof(size_t));
/* column count */
if (fread(&count, sizeof(char), sizeof(count), pCur->output) != sizeof(count)) {
fprintf(stderr, "Error: Could not read column count\n");
goto error;
}

curr += sizeof(int);
/* buf does not contain row prefix */
buf = malloc(row_len - row_prefix);
curr = buf;
starts = malloc(count * sizeof(size_t));

char *new_buf = NULL;
for(int i = 0; i < count; i++) {
/* column start points to type */
starts[i] = curr - buf;

/* add space for type and length */
size += TL;

curr_offset = curr - buf;

/* reallocate buffer for type and length */
new_buf = realloc(buf, size);
if (!new_buf) {
const int err = errno;
fprintf(stderr, "Error: Could not resize buffer for reading column type and length. New size: %zu: %s (%d)\n",
size, strerror(err), err);
goto error;
}

buf = new_buf;
curr = buf + curr_offset;

/* read type and length */
const size_t tl = fread(curr, sizeof(char), TL, pCur->output);
if (tl != TL) {
Expand All @@ -253,34 +245,19 @@ static int gufi_query_read_row(gufi_vtab_cursor *pCur) {

const size_t value_len = * (size_t *) (curr + sizeof(char));

size += value_len; /* update buffer size with value length */
curr += TL; /* to go to end of buffer/start of value */

curr_offset = curr - buf;

/* allocate space for value */
new_buf = realloc(buf, size);
if (!new_buf) {
const int err = errno;
fprintf(stderr, "Error: Could not resize buffer for reading column value. New size: %zu: %s (%d)\n",
size, strerror(err), err);
goto error;
}

buf = new_buf;
curr = buf + curr_offset;
curr += TL; /* to go to start of value */

const size_t v = fread(curr, sizeof(char), value_len, pCur->output);
if (v != value_len) {
fprintf(stderr, "Eror: Could not read %zu octets. Got %zu\n", value_len, v);
fprintf(stderr, "Error: Could not read %zu octets. Got %zu\n", value_len, v);
goto error;
}

curr += value_len;
}

pCur->row = buf;
pCur->len = size;
pCur->len = row_len;
pCur->col_starts = starts;
pCur->col_count = count;

Expand Down
13 changes: 10 additions & 3 deletions src/print.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ int print_parallel(void *args, int count, char **data, char **columns) {
}

if (types) {
row_len += sizeof(count); /* start row with column count */
row_len += sizeof(row_len) + sizeof(count); /* start row with row length and column count */
row_len += count * (sizeof(char) + sizeof(size_t)); /* type and length per column */
}
else {
Expand All @@ -111,8 +111,11 @@ int print_parallel(void *args, int count, char **data, char **columns) {
pthread_mutex_lock(print->mutex);
}

/* write column count */
if (types) {
/* write total row length */
fwrite(&row_len, sizeof(char), sizeof(row_len), print->outfile);

/* write column count */
fwrite(&count, sizeof(char), sizeof(count), print->outfile);
}

Expand Down Expand Up @@ -163,8 +166,12 @@ int print_parallel(void *args, int count, char **data, char **columns) {
char *buf = ob->buf;
size_t filled = ob->filled;

/* write column count */
if (types) {
/* write row length */
memcpy(&buf[filled], &row_len, sizeof(row_len));
filled += sizeof(row_len);

/* write column count */
memcpy(&buf[filled], &count, sizeof(count));
filled += sizeof(count);
}
Expand Down
15 changes: 8 additions & 7 deletions test/regression/gufi_query.expected
Original file line number Diff line number Diff line change
Expand Up @@ -222,16 +222,17 @@ prefix/unusual#? directory ,/unusual, name?#

# Output TLV columns (no aggregation)
$ gufi_query -u -n 2 -E "SELECT name, size FROM vrpentries WHERE name == '.hidden';" "prefix" | od -x --endian=big
0000000 0200 0000 0307 0000 0000 0000 002e 6869
0000020 6464 656e 0102 0000 0000 0000 0031 3000
0000037
0000000 2700 0000 0000 0000 0200 0000 0307 0000
0000020 0000 0000 002e 6869 6464 656e 0102 0000
0000040 0000 0000 0031 3000
0000047

# Output TLV columns (with aggregation)
$ gufi_query -u -d " " -n 2 -a -I "CREATE TABLE out(path TEXT, size INT64);" -K "CREATE TABLE aggregate(path TEXT, size INT64);" -S "INSERT INTO out SELECT rpath(sname, sroll), size FROM vrsummary;" -E "INSERT INTO out SELECT rpath(sname, sroll) || '/' || name, size FROM vrpentries;" -J "INSERT INTO aggregate SELECT path, size FROM out;" -G "SELECT path, size FROM aggregate ORDER BY path ASC LIMIT 1;" "prefix" | od -x --endian=big
0000000 0200 0000 030d 0000 0000 0000 0073 6561
0000020 7263 682f 7072 6566 6978 0102 0000 0000
0000040 0000 0031 3700
0000045
0000000 2d00 0000 0000 0000 0200 0000 030d 0000
0000020 0000 0000 0073 6561 7263 682f 7072 6566
0000040 6978 0102 0000 0000 0000 0031 3700
0000055

#####################################
# Invalid Inputs #
Expand Down
5 changes: 5 additions & 0 deletions test/unit/googletest/print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ static void print_parallel_tlv_actual(const bool use_len) {
};

const std::size_t total_len =
sizeof(std::size_t) + // row length
sizeof(int) + // number of columns
INTEGER.size() + FLOAT.size() + TEXT.size() +
BLOB.size() + NULL_.size() + DATE.size() +
Expand Down Expand Up @@ -242,6 +243,10 @@ static void print_parallel_tlv_actual(const bool use_len) {

char *curr = buf;

// column_count
EXPECT_EQ((std::size_t) * (int *) curr, total_len);
curr += sizeof(std::size_t);

// column_count
EXPECT_EQ((std::size_t) * (int *) curr, COL_COUNT);
curr += sizeof(int);
Expand Down

0 comments on commit 09b36e7

Please sign in to comment.