mmap-page-boundary iterate

This commit is contained in:
John Kerl 2016-01-19 22:17:05 -05:00
parent db4eb7d443
commit d7676c5441
4 changed files with 27 additions and 12 deletions

View file

@ -123,6 +123,7 @@ lrec_t* lrec_parse_mmap_dkvp_single_irs_single_others(file_reader_mmap_state_t *
int saw_ps = FALSE;
int saw_rs = FALSE;
//*phandle->eof = 'A'; // xxx temp
for ( ; p < phandle->eof && *p; ) {
if (*p == irs) {
*p = 0;
@ -170,7 +171,8 @@ lrec_t* lrec_parse_mmap_dkvp_single_irs_single_others(file_reader_mmap_state_t *
// There are two ways out of that loop: saw IRS, or saw end of file.
if (saw_rs) {
// Easy and simple case: we read until end of line.
// Easy and simple case: we read until end of line. We zero-poked the irs to a null character to terminate the
// C string so it's OK to retain a pointer to that.
if (*key == 0 || value <= key) {
char free_flags = 0;
@ -187,20 +189,27 @@ lrec_t* lrec_parse_mmap_dkvp_single_irs_single_others(file_reader_mmap_state_t *
}
} else {
// Messier case: we read to end of file without seeing end of line.
// Messier case: we read to end of file without seeing end of line. We can't always zero-poke a null character
// to terminate the C string: if the file size is not a multiple of the OS page size it'll work (it's our
// copy-on-write memory). But if the file size is a multiple of the page size, then zero-poking at EOF is one
// byte past the page and that will segv us.
if (*key == 0 || value <= key) {
char free_flags = 0;
if (value >= phandle->eof)
if (value >= phandle->eof) {
lrec_put(prec, make_nidx_key(idx, &free_flags), "", free_flags);
else
lrec_put(prec, make_nidx_key(idx, &free_flags), value, free_flags);
} else {
char* copy = mlr_alloc_string_from_char_range(value, phandle->eof - value);
lrec_put(prec, make_nidx_key(idx, &free_flags), copy, free_flags | FREE_ENTRY_VALUE);
}
}
else {
if (value >= phandle->eof)
if (value >= phandle->eof) {
lrec_put(prec, key, "", NO_FREE);
else
lrec_put(prec, key, value, NO_FREE);
} else {
char* copy = mlr_alloc_string_from_char_range(value, phandle->eof - value);
lrec_put(prec, key, copy, FREE_ENTRY_VALUE);
}
}
}

View file

@ -194,10 +194,7 @@ void copy_regex_captures(string_array_t* pregex_captures_1_up, char* input, regm
string_array_realloc(pregex_captures_1_up, n+1); // n+1 since slot 0 of this 1-up array is unused
for (int i = 1; i <= n; i++) {
int len = matches[i].rm_eo - matches[i].rm_so;
char* dst = mlr_malloc_or_die(len + 1);
memcpy(dst, &input[matches[i].rm_so], len);
dst[len] = 0;
pregex_captures_1_up->strings[i] = dst;
pregex_captures_1_up->strings[i] = mlr_alloc_string_from_char_range(&input[matches[i].rm_so], len);
}
pregex_captures_1_up->strings_need_freeing = TRUE;
}

View file

@ -119,6 +119,13 @@ char* mlr_alloc_string_from_int(int value) {
return string;
}
char* mlr_alloc_string_from_char_range(char* start, int num_bytes) {
char* string = mlr_malloc_or_die(num_bytes+1);
memcpy(string, start, num_bytes);
string[num_bytes] = 0;
return string;
}
char* mlr_alloc_hexfmt_from_ll(long long value) {
int n = snprintf(NULL, 0, "0x%llx", (unsigned long long)value);
char* string = mlr_malloc_or_die(n+1);

View file

@ -90,6 +90,8 @@ char* mlr_alloc_string_from_ull(unsigned long long value);
char* mlr_alloc_string_from_ll(long long value);
char* mlr_alloc_string_from_ll_and_format(long long value, char* fmt);
char* mlr_alloc_string_from_int(int value);
// The input doesn't include the null-terminator; the output does.
char* mlr_alloc_string_from_char_range(char* start, int num_bytes);
char* mlr_alloc_hexfmt_from_ll(long long value);