mirror of
https://github.com/XTXMarkets/ternfs.git
synced 2025-12-21 10:40:04 -06:00
170 lines
5.6 KiB
C
170 lines
5.6 KiB
C
// Copyright 2025 XTX Markets Technologies Limited
|
|
//
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <immintrin.h>
|
|
#include <stdbool.h>
|
|
|
|
typedef uint8_t u8;
|
|
typedef uint16_t u16;
|
|
typedef uint32_t u32;
|
|
typedef uint64_t u64;
|
|
|
|
#define likely(x) __builtin_expect(!!(x), 1)
|
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
|
|
|
#define BUG_ON(x) \
|
|
if (unlikely(x)) { \
|
|
fprintf(stderr, "bug: " #x); \
|
|
fprintf(stderr, "\n"); \
|
|
exit(1); \
|
|
}
|
|
|
|
#define TERNFS_UDP_MTU 1472
|
|
|
|
static inline u64 get_unaligned_le64(const void* p) {
|
|
u64 x;
|
|
memcpy(&x, p, sizeof(x));
|
|
return x;
|
|
}
|
|
static inline u32 get_unaligned_le32(const void* p) {
|
|
u32 x;
|
|
memcpy(&x, p, sizeof(x));
|
|
return x;
|
|
}
|
|
static inline u16 get_unaligned_le16(const void* p) {
|
|
u16 x;
|
|
memcpy(&x, p, sizeof(x));
|
|
return x;
|
|
}
|
|
|
|
static inline u64 get_unaligned_be64(const void* p) {
|
|
u64 x;
|
|
memcpy(&x, p, sizeof(x));
|
|
return __bswap_64(x);
|
|
}
|
|
static inline u32 get_unaligned_be32(const void* p) {
|
|
u32 x;
|
|
memcpy(&x, p, sizeof(x));
|
|
return __bswap_32(x);
|
|
}
|
|
|
|
static inline void put_unaligned_le64(u64 x, void* p) {
|
|
memcpy(p, &x, sizeof(x));
|
|
}
|
|
static inline void put_unaligned_le32(u32 x, void* p) {
|
|
memcpy(p, &x, sizeof(x));
|
|
}
|
|
static inline void put_unaligned_le16(u16 x, void* p) {
|
|
memcpy(p, &x, sizeof(x));
|
|
}
|
|
|
|
static inline void put_unaligned_be64(u64 x, void* p) {
|
|
x = __bswap_64(x);
|
|
memcpy(p, &x, sizeof(x));
|
|
}
|
|
static inline void put_unaligned_be32(u32 x, void* p) {
|
|
x = __bswap_32(x);
|
|
memcpy(p, &x, sizeof(x));
|
|
}
|
|
|
|
#include "bincode.h"
|
|
|
|
int main(void) {
|
|
{
|
|
char lookup_req[TERNFS_LOOKUP_REQ_MAX_SIZE];
|
|
struct ternfs_bincode_put_ctx put_ctx = {
|
|
.start = lookup_req,
|
|
.cursor = lookup_req,
|
|
.end = lookup_req + sizeof(lookup_req),
|
|
};
|
|
{
|
|
ternfs_lookup_req_put_start(&put_ctx, start);
|
|
ternfs_lookup_req_put_dir_id(&put_ctx, start, dir_id, 123);
|
|
ternfs_lookup_req_put_name(&put_ctx, dir_id, name, "foo", 3);
|
|
ternfs_lookup_req_put_end(&ctx, name, end);
|
|
}
|
|
struct ternfs_bincode_get_ctx get_ctx = {
|
|
.buf = put_ctx.start,
|
|
.end = put_ctx.cursor,
|
|
.err = 0,
|
|
};
|
|
{
|
|
ternfs_lookup_req_get_start(&get_ctx, start);
|
|
ternfs_lookup_req_get_dir_id(&get_ctx, start, dir_id);
|
|
ternfs_lookup_req_get_name(&get_ctx, dir_id, name);
|
|
ternfs_lookup_req_get_end(&get_ctx, name, end);
|
|
ternfs_lookup_req_get_finish(&get_ctx, end);
|
|
BUG_ON(get_ctx.err != 0);
|
|
BUG_ON(dir_id.x != 123);
|
|
BUG_ON(name.str.len != 3);
|
|
BUG_ON(strncmp("foo", name.str.buf, 3) != 0);
|
|
}
|
|
}
|
|
|
|
{
|
|
char read_dir_resp[TERNFS_UDP_MTU];
|
|
struct ternfs_bincode_put_ctx put_ctx = {
|
|
.start = read_dir_resp,
|
|
.cursor = read_dir_resp,
|
|
.end = read_dir_resp + sizeof(read_dir_resp),
|
|
};
|
|
{
|
|
ternfs_read_dir_resp_put_start(&put_ctx, start);
|
|
ternfs_read_dir_resp_put_next_hash(&put_ctx, start, next_hash, 123);
|
|
ternfs_read_dir_resp_put_results(&put_ctx, next_hash, results, 3);
|
|
for (int i = 0; i < 3; i++) {
|
|
ternfs_current_edge_put_start(&put_ctx, edge_start);
|
|
ternfs_current_edge_put_target_id(&put_ctx, edge_start, target_id, i);
|
|
ternfs_current_edge_put_name_hash(&put_ctx, target_id, name_hash, i + 42);
|
|
char name_str[2];
|
|
snprintf(name_str, 2, "%d", i);
|
|
ternfs_current_edge_put_name(&put_ctx, name_hash, name, name_str, 1);
|
|
ternfs_current_edge_put_creation_time(&put_ctx, name, creation_time, i + 1000);
|
|
ternfs_current_edge_put_end(&put_ctx, creation_time, end);
|
|
}
|
|
ternfs_read_dir_resp_put_end(&ctx, results, end);
|
|
}
|
|
struct ternfs_bincode_get_ctx get_ctx = {
|
|
.buf = put_ctx.start,
|
|
.end = put_ctx.cursor,
|
|
.err = 0,
|
|
};
|
|
{
|
|
ternfs_read_dir_resp_get_start(&get_ctx, start);
|
|
ternfs_read_dir_resp_get_next_hash(&get_ctx, start, next_hash);
|
|
ternfs_read_dir_resp_get_results(&get_ctx, next_hash, results);
|
|
for (int i = 0; i < results.len; i++) {
|
|
ternfs_current_edge_get_start(&get_ctx, edge_start);
|
|
ternfs_current_edge_get_target_id(&get_ctx, edge_start, target_id);
|
|
ternfs_current_edge_get_name_hash(&get_ctx, target_id, name_hash);
|
|
ternfs_current_edge_get_name(&get_ctx, name_hash, name);
|
|
ternfs_current_edge_get_creation_time(&get_ctx, name, creation_time);
|
|
ternfs_current_edge_get_end(&put_ctx, creation_time, end);
|
|
ternfs_bincode_get_finish_list_el(end);
|
|
if (get_ctx.err == 0) {
|
|
BUG_ON(target_id.x != i);
|
|
BUG_ON(name_hash.x != i + 42);
|
|
BUG_ON(name.str.len != 1);
|
|
char name_str[11];
|
|
snprintf(name_str, 11, "%d", i);
|
|
BUG_ON(strlen(name_str) != 1);
|
|
BUG_ON(strncmp(name.str.buf, name_str, 1) != 0);
|
|
BUG_ON(creation_time.x != i + 1000);
|
|
}
|
|
}
|
|
ternfs_read_dir_resp_get_end(&get_ctx, results, end);
|
|
ternfs_read_dir_resp_get_finish(&get_ctx, end);
|
|
BUG_ON(get_ctx.err != 0);
|
|
BUG_ON(next_hash.x != 123);
|
|
}
|
|
}
|
|
|
|
printf("All tests pass.\n");
|
|
|
|
return 0;
|
|
} |