fix offset delta calculations, add get_or_insert

This commit is contained in:
Alain Zscheile 2023-01-02 10:48:29 +01:00
parent a00e9a7dcd
commit 82d7e110ec
2 changed files with 54 additions and 6 deletions

46
idx.c
View file

@ -23,7 +23,7 @@ int y16t_idx_lookup(
if(fread(result, 4, 1, fh) != 1)
return -EIO;
*result = ntohl(*result);
if(key && fseek(fh, -key, SEEK_CUR) == -1)
if(fseek(fh, -key - 4, SEEK_CUR) == -1)
return -EIO;
return 0;
@ -42,7 +42,45 @@ int y16t_idx_update(
return -EIO;
if(fwrite(&odval, 4, 1, fh) != 1)
return -EIO;
if(key && fseek(fh, -key, SEEK_CUR) == -1)
if(fseek(fh, -key - 4, SEEK_CUR) == -1)
return -EIO;
return 0;
}
int y16t_idx_get_or_insert(
FILE *fh,
const uint8_t x,
const uint8_t y,
uint32_t *value,
uint32_t (*palloc)(void*),
void *context
) {
const long key = y16t_table_at(x, y);
if(key && fseek(fh, key, SEEK_CUR) == -1)
return -EIO;
uint32_t value_tmp = 0;
if(fread(&value_tmp, 4, 1, fh) != 1)
return -EIO;
if(!value_tmp) {
// allocate new entry
value_tmp = palloc(context);
if(!value_tmp)
return -ENOMEM;
value_tmp = htonl(value_tmp);
if(fseek(fh, -4, SEEK_CUR) == -1)
return -EIO;
if(fwrite(&value_tmp, 4, 1, fh) != 1)
return -EIO;
}
*value = ntohl(value_tmp);
if(fseek(fh, -key - 4, SEEK_CUR) == -1)
return -EIO;
return 0;
@ -60,12 +98,12 @@ static int y16t_idx_foreach_inner(
const long delta = ((long)key) - *offset;
if(delta && fseek(fh, delta, SEEK_CUR) == -1)
return -EIO;
*offset = key;
*offset = key + 4;
uint32_t value = 0;
if(fread(&value, 4, 1, fh) != 1)
return -EIO;
const int tmp = callback(ntohl(value), context);
if(tmp && *offset) {
if(tmp) {
fseek(fh, -*offset, SEEK_CUR);
*offset = 0;
}

14
y16t.h
View file

@ -4,8 +4,8 @@
#include <stddef.h>
#include <stdio.h>
// try to lookup the given coordinates, and return the corresponding location
// via `result`.
// try to lookup the given coordinates,
// and return the corresponding location via `result`.
// the file given as `fh` is expected to be at least 256KiB large
// returns a negative errno number in case of failure
__attribute__((nonnull))
@ -25,6 +25,16 @@ int y16t_idx_update(
uint32_t newval
);
// insert a table entry if it doesn't already exist
int y16t_idx_get_or_insert(
FILE *fh,
uint8_t x,
uint8_t y,
uint32_t *value,
uint32_t (*palloc)(void*),
void *context
);
// iterate over columns or rows
int y16t_idx_foreach_x(
FILE *fh,