skip to content
==> include/mesh/jobs/id.h <==
1/* @ajax/mesh-jobs-id: a job's id and a payload's hash, and their text forms (jobs.rs).
2 *
3 * A job id is `t.n`: the n-th job submitted in fleet term t (term in the high 32 bits). A payload's
4 * hash is its sha256, named in lowercase hex. */
5#ifndef MESH_JOBS_ID_H
6#define MESH_JOBS_ID_H
7
8#include <stdbool.h>
9#include <stdint.h>
10#include <string.h>
11
12typedef uint64_t mj_job_id;
13
14typedef struct {
15    uint8_t b[32];
16} mj_hash;
17
18#define MJ_JOB_WORD_MAX 32 /* "4294967295.4294967295" and its NUL fit */
19
20/* `t.n` into out. */
21void mj_job_word(mj_job_id id, char out[MJ_JOB_WORD_MAX]);
22/* `t.n` (t a u64, shifted up 32 bits; n a u32); false when it isn't one. */
23bool mj_parse_job(const char *s, mj_job_id *out);
24/* 64 lowercase hex digits into out. */
25void mj_hex(const mj_hash *h, char out[65]);
26/* Exactly 64 hex digits (each pair as Rust's u8::from_str_radix reads it); false otherwise. */
27bool mj_unhex(const char *s, mj_hash *out);
28
29static inline bool mj_hash_eq(const mj_hash *a, const mj_hash *b) { return memcmp(a->b, b->b, 32) == 0; }
30/* The hash as four big-endian words: ordered as the bytes are (a map key). */
31static inline void mj_hash_words(const mj_hash *h, uint64_t w[4]) {
32    for (int i = 0; i < 4; i++) {
33        uint64_t x = 0;
34        for (int j = 0; j < 8; j++) x = x << 8 | h->b[8 * i + j];
35        w[i] = x;
36    }
37}
38static inline mj_hash mj_hash_of_words(const uint64_t w[4]) {
39    mj_hash h;
40    for (int i = 0; i < 4; i++)
41        for (int j = 0; j < 8; j++) h.b[8 * i + j] = (uint8_t)(w[i] >> (56 - 8 * j));
42    return h;
43}
44
45#endif