2022-12-18 02:15:58 +00:00
|
|
|
// SPDX-License-Identifier: ISC
|
2023-01-03 08:40:10 +00:00
|
|
|
#include "y16t_idx.h"
|
2023-01-02 08:55:12 +00:00
|
|
|
#include "y16t_internal.h"
|
2022-12-18 02:15:58 +00:00
|
|
|
#include <arpa/inet.h>
|
2023-01-01 00:26:17 +00:00
|
|
|
#include <errno.h>
|
2023-01-03 06:55:00 +00:00
|
|
|
#include <unistd.h>
|
2022-12-18 02:15:58 +00:00
|
|
|
|
2023-01-04 08:47:58 +00:00
|
|
|
#include "hilbert.c"
|
|
|
|
|
2023-01-01 00:26:17 +00:00
|
|
|
static __attribute__((pure))
|
2023-01-03 06:55:00 +00:00
|
|
|
uint32_t y16t_table_at(const y16t_idx_t idx, const uint8_t x, const uint8_t y)
|
2023-01-01 00:26:17 +00:00
|
|
|
{
|
2023-01-04 08:08:09 +00:00
|
|
|
return (idx.offset << 12)
|
2023-01-03 06:55:00 +00:00
|
|
|
| (y16t_hilbert_xy2d(1 << 16, x, y) << 2);
|
2023-01-01 00:26:17 +00:00
|
|
|
}
|
|
|
|
|
2023-01-03 06:55:00 +00:00
|
|
|
static __attribute__((pure))
|
|
|
|
int y16t_idx_hret(const int tmp)
|
|
|
|
{
|
|
|
|
if(tmp == 4) {
|
|
|
|
return 0;
|
|
|
|
} else if(tmp < 0) {
|
|
|
|
return tmp;
|
|
|
|
} else {
|
2023-01-02 08:33:51 +00:00
|
|
|
return -EIO;
|
2023-01-03 06:55:00 +00:00
|
|
|
}
|
|
|
|
}
|
2023-01-01 00:26:17 +00:00
|
|
|
|
2023-01-03 06:55:00 +00:00
|
|
|
int y16t_idx_lookup(
|
|
|
|
y16t_idx_t idx,
|
|
|
|
uint8_t x,
|
|
|
|
uint8_t y,
|
|
|
|
uint32_t *result
|
|
|
|
) {
|
|
|
|
const off_t key = y16t_table_at(idx, x, y);
|
|
|
|
const int tmp = y16t_idx_hret(y16t_pread_all(idx.fd, result, 4, key));
|
|
|
|
if(tmp >= 0) *result = ntohl(*result);
|
|
|
|
return tmp;
|
2023-01-01 00:26:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int y16t_idx_update(
|
2023-01-03 06:55:00 +00:00
|
|
|
y16t_idx_t idx,
|
2023-01-01 00:26:17 +00:00
|
|
|
const uint8_t x,
|
|
|
|
const uint8_t y,
|
|
|
|
const uint32_t newval
|
2022-12-18 02:15:58 +00:00
|
|
|
) {
|
2023-01-03 06:55:00 +00:00
|
|
|
const off_t key = y16t_table_at(idx, x, y);
|
2023-01-02 08:55:12 +00:00
|
|
|
const uint32_t odval = htonl(newval);
|
2023-01-03 06:55:00 +00:00
|
|
|
return y16t_idx_hret(y16t_pwrite_all(idx.fd, &odval, 4, key));
|
2023-01-02 09:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int y16t_idx_get_or_insert(
|
2023-01-03 06:55:00 +00:00
|
|
|
y16t_idx_t idx,
|
2023-01-02 09:48:29 +00:00
|
|
|
const uint8_t x,
|
|
|
|
const uint8_t y,
|
2023-01-03 06:55:00 +00:00
|
|
|
uint32_t *value,
|
|
|
|
uint32_t (*palloc)(void*),
|
|
|
|
void *context
|
2023-01-02 09:48:29 +00:00
|
|
|
) {
|
2023-01-03 06:55:00 +00:00
|
|
|
const long key = y16t_table_at(idx, x, y);
|
2023-01-02 09:48:29 +00:00
|
|
|
uint32_t value_tmp = 0;
|
2023-01-03 06:55:00 +00:00
|
|
|
int tmp = y16t_idx_hret(y16t_pread_all(idx.fd, &value_tmp, 4, key));
|
|
|
|
if(tmp < 0)
|
|
|
|
return tmp;
|
2023-01-02 09:48:29 +00:00
|
|
|
|
|
|
|
if(!value_tmp) {
|
|
|
|
// allocate new entry
|
|
|
|
value_tmp = palloc(context);
|
|
|
|
if(!value_tmp)
|
|
|
|
return -ENOMEM;
|
|
|
|
value_tmp = htonl(value_tmp);
|
2023-01-03 06:55:00 +00:00
|
|
|
tmp = y16t_idx_hret(y16t_pwrite_all(idx.fd, &value_tmp, 4, key));
|
2023-01-02 09:48:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*value = ntohl(value_tmp);
|
2023-01-03 06:55:00 +00:00
|
|
|
return tmp;
|
2022-12-18 02:15:58 +00:00
|
|
|
}
|
|
|
|
|
2023-01-02 09:05:47 +00:00
|
|
|
static int y16t_idx_foreach_inner(
|
2023-01-03 06:55:00 +00:00
|
|
|
y16t_idx_t idx,
|
2023-01-02 09:05:47 +00:00
|
|
|
uint8_t x,
|
|
|
|
uint8_t y,
|
2023-01-04 08:17:59 +00:00
|
|
|
uint8_t oth,
|
|
|
|
int (*callback)(uint8_t, uint32_t, void*),
|
2023-01-02 09:05:47 +00:00
|
|
|
void *context
|
|
|
|
) {
|
|
|
|
uint32_t value = 0;
|
2023-01-04 08:17:59 +00:00
|
|
|
const int tmp = y16t_idx_lookup(idx, x, y, &value);
|
2023-01-03 06:55:00 +00:00
|
|
|
if(tmp < 0) return tmp;
|
2023-01-04 08:17:59 +00:00
|
|
|
return callback(oth, ntohl(value), context);
|
2023-01-02 09:05:47 +00:00
|
|
|
}
|
|
|
|
|
2023-01-01 00:26:17 +00:00
|
|
|
int y16t_idx_foreach_x(
|
2023-01-03 06:55:00 +00:00
|
|
|
y16t_idx_t idx,
|
|
|
|
uint8_t y,
|
2023-01-04 08:17:59 +00:00
|
|
|
int (*callback)(uint8_t, uint32_t, void*),
|
2023-01-03 06:55:00 +00:00
|
|
|
void *context
|
2022-12-18 02:15:58 +00:00
|
|
|
) {
|
2023-01-01 00:26:17 +00:00
|
|
|
for (uint16_t x = 0; x < 0xff; ++x) {
|
2023-01-04 08:17:59 +00:00
|
|
|
const int tmp = y16t_idx_foreach_inner(idx, x, y, x, callback, context);
|
2023-01-02 08:55:12 +00:00
|
|
|
if(tmp) return tmp;
|
2022-12-18 02:15:58 +00:00
|
|
|
}
|
2023-01-02 08:33:51 +00:00
|
|
|
|
2023-01-01 00:26:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2022-12-18 02:15:58 +00:00
|
|
|
|
2023-01-01 00:26:17 +00:00
|
|
|
int y16t_idx_foreach_y(
|
2023-01-03 06:55:00 +00:00
|
|
|
y16t_idx_t idx,
|
|
|
|
uint8_t x,
|
2023-01-04 08:17:59 +00:00
|
|
|
int (*callback)(uint8_t, uint32_t, void*),
|
2023-01-03 06:55:00 +00:00
|
|
|
void *context
|
2023-01-01 00:26:17 +00:00
|
|
|
) {
|
|
|
|
for (uint16_t y = 0; y < 0xff; ++y) {
|
2023-01-04 08:17:59 +00:00
|
|
|
const int tmp = y16t_idx_foreach_inner(idx, x, y, y, callback, context);
|
2023-01-02 08:55:12 +00:00
|
|
|
if(tmp) return tmp;
|
2023-01-01 00:26:17 +00:00
|
|
|
}
|
2023-01-02 08:33:51 +00:00
|
|
|
|
2023-01-01 00:26:17 +00:00
|
|
|
return 0;
|
2022-12-18 02:15:58 +00:00
|
|
|
}
|