From 3488b6271662aab21be8ee5ea16a03eaf0090ca2 Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Wed, 19 Nov 2025 14:44:49 +0800 Subject: [PATCH] jobid format and parse --- src/include/config.h | 9 ++- src/include/utils.h | 31 ++++++++-- src/lib/testsuite/test_idgen.c | 21 ++++++- src/lib/testsuite/test_utils.c | 40 ++++++++++++ src/lib/utils.c | 108 +++++++++++++++++++++++++++++++++ src/meson.build | 18 +++--- 6 files changed, 212 insertions(+), 15 deletions(-) diff --git a/src/include/config.h b/src/include/config.h index 1d99c8e..f85e856 100644 --- a/src/include/config.h +++ b/src/include/config.h @@ -41,16 +41,21 @@ typedef uint64_t jobid_t; #define N_ARRAY_IDX_BITS (15) -#define N_SEQENCE_BITS \ +#define N_SEQUENCE_BITS \ (N_JOBID_BITS - N_CLUSTER_ID_BITS - N_APISERVER_ID_BITS - N_TIMESTAMP_BITS \ - N_TAG_BITS) #define SEQUENCE_HIGH_SHIFT (N_ARRAY_IDX_BITS) -#define UMAX_BITS(w) ((((uint64_t)0x01) << (int)w) - 1) +#define N_MAX_FIELDS_JOBID (5) + +#define UMAX_BITS(w) ((((uint64_t)0x01) << ((int)w)) - 1) #define MAX_CLUSTER_ID (UMAX_BITS(N_CLUSTER_ID_BITS)) #define MAX_APISERVER_ID (UMAX_BITS(N_APISERVER_ID_BITS)) #define MAX_ARRAY_IDX (UMAX_BITS(N_ARRAY_IDX_BITS)) +#define REGEX_JOBID "[ \t]*([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)[ \t]*" +#define REGEX_JOBARRAY_ID "[ \t]*([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\\[([0-9]+)\\][ \t]*" + #endif diff --git a/src/include/utils.h b/src/include/utils.h index 973324a..9f6dfa7 100644 --- a/src/include/utils.h +++ b/src/include/utils.h @@ -18,7 +18,30 @@ ((((uint64_t)cluster) << CLUSTER_ID_SHIFT) \ | (((uint64_t)apiserver) << APISERVER_ID_SHIFT) \ | (((uint64_t)timestamp) << TIMESTAMP_SHIFT) \ - | (((uint64_t)tag) << TAG_SHIFT) | sequence) + | (((uint64_t)tag) << TAG_SHIFT) | (sequence)) + +#define EXTRACT_BITS(id, shift, bits) (((id) >> (shift)) & (UMAX_BITS(bits))) + +#define EXTRACT_ID_TAG(id) EXTRACT_BITS(id, TAG_SHIFT, N_TAG_BITS) + +#define EXTRACT_ID_CLUSTER(id) \ + EXTRACT_BITS(id, CLUSTER_ID_SHIFT, N_CLUSTER_ID_BITS) + +#define EXTRACT_ID_APISERVER(id) \ + EXTRACT_BITS(id, APISERVER_ID_SHIFT, N_APISERVER_ID_BITS) + +#define EXTRACT_ID_TIMESTAMP(id) \ + EXTRACT_BITS(id, TIMESTAMP_SHIFT, N_TIMESTAMP_BITS) + +#define EXTRACT_ID_SEQUENCE(id) EXTRACT_BITS(id, 0, N_SEQUENCE_BITS) + +#define EXTRACT_ARRAY_JOB(id) \ + ((((id) >> SEQUENCE_HIGH_SHIFT) \ + & UMAX_BITS(N_SEQUENCE_BITS - SEQUENCE_HIGH_SHIFT)) \ + << SEQUENCE_HIGH_SHIFT) + +#define EXTRACT_ARRAY_IDX(id) \ + EXTRACT_BITS(id, 0, (N_SEQUENCE_BITS - SEQUENCE_HIGH_SHIFT)) #define ROUNDUP(v, bits) (((v) + UMAX_BITS(bits)) & ~UMAX_BITS(bits)) @@ -44,9 +67,6 @@ #define N_EL_ARRAY(arr) (sizeof(arr) / sizeof(arr[0])) #define PTR_STEP(p, delta) ((void*)(((char*)p) + (delta))) -#define N_EL_ARRAY(arr) (sizeof(arr) / sizeof(arr[0])) -#define PTR_STEP(p, delta) ((void*)(((char*)p) + (delta))) - /* move the owner ship of pointer from src to dst */ #define MOVE_PTR(dst, src) \ do { \ @@ -100,4 +120,7 @@ extern xce_res_threshold_t** dup_resource_thresholds(xce_res_threshold_t**, extern void free_resval_with_idx_list(xce_val_with_idx_t***, int); extern void free_strlist(xce_strlist_t*); +extern int fmt_jobid(char*, size_t, uint64_t); +extern int parse_jobid(uint64_t*, char*); + #endif diff --git a/src/lib/testsuite/test_idgen.c b/src/lib/testsuite/test_idgen.c index 2fb27c8..3031a56 100644 --- a/src/lib/testsuite/test_idgen.c +++ b/src/lib/testsuite/test_idgen.c @@ -4,6 +4,7 @@ #include #include "idgen.h" +#include "utils.h" #include static void test_idgen_invalid(void) @@ -35,9 +36,13 @@ static void test_idgen1(void) TEST_ASSERT_TRUE(rc >= 0); for (i = 0; i < 20; i++) { + char buf[256]; + rc = idgen(&ctx, 0x0, 0x0, 1, &idx); TEST_ASSERT_TRUE(rc >= 0); - printf("\tidx = %lx\n", idx); + memset(buf, 0x0, sizeof(buf)); + fmt_jobid(buf, sizeof(buf), idx); + printf("\tjob = %s idx %lx\n", buf, idx); } idgen_ctx_fini(&ctx); @@ -56,12 +61,24 @@ static void test_idgen_array(void) int k; for (k = 0; k < 5; k++) { + int j; + rc = idgen(&ctx, 0x0, 0x0, i + 1, &idx); TEST_ASSERT_TRUE(rc >= 0); if (i >= 1) { TEST_ASSERT_TRUE((idx & MAX_ARRAY_IDX) == 0); } - printf("\tidx = %lx\n", idx); + + for (j = 0; j < i; j++) { + char buf[256]; + + memset(buf, 0x0, sizeof(buf)); + + fmt_jobid(buf, sizeof(buf), idx + j); + printf("\tjob = %s idx %lx \n", buf, idx + j); + } + + printf("\n"); } } diff --git a/src/lib/testsuite/test_utils.c b/src/lib/testsuite/test_utils.c index 0df83a3..b9263c0 100644 --- a/src/lib/testsuite/test_utils.c +++ b/src/lib/testsuite/test_utils.c @@ -99,6 +99,43 @@ void test_roundup(void) TEST_ASSERT_TRUE(ROUNDUP(31, 5) == 32); } +void test_extract_bits(void) { + uint64_t id = 0xfefefefeffff; + + TEST_ASSERT_TRUE(EXTRACT_BITS(id, 0, 4) == 0xf); + TEST_ASSERT_TRUE(EXTRACT_BITS(id, 16, 4) == 0xe); + TEST_ASSERT_TRUE(EXTRACT_BITS(id, 16, 8) == 0xfe); + TEST_ASSERT_TRUE(EXTRACT_BITS(id, 20, 12) == 0xfef); + TEST_ASSERT_TRUE(EXTRACT_BITS(id, 44, 4) == 0xf); + TEST_ASSERT_TRUE(EXTRACT_BITS(id, 40, 8) == 0xfe); +} + +static void do_parse_jobid_test(uint64_t jobid) { + uint64_t jobid2; + int rc; + char buf[256]; + + rc = fmt_jobid(buf, sizeof(buf), jobid); + printf("\t\tCheck jobid %s\n", buf); + + TEST_ASSERT_TRUE(rc > 0); + rc = parse_jobid(&jobid2, buf); + TEST_ASSERT_TRUE(rc >= 0); + TEST_ASSERT_TRUE(jobid == jobid2); +} + +void test_parse_jobid1(void) { + uint64_t jobid = 0x400691c2fd498003; + + do_parse_jobid_test(jobid); +} + +void test_parse_jobid2(void) { + uint64_t jobid = 0x691d3c1d00013; + + do_parse_jobid_test(jobid); +} + void test_utils(void) { printf("\n>> utils test\n\n"); @@ -106,4 +143,7 @@ void test_utils(void) RUN_TEST(test_timewindow_config_dup); RUN_TEST(test_dup_threshold); RUN_TEST(test_roundup); + RUN_TEST(test_extract_bits); + RUN_TEST(test_parse_jobid1); + RUN_TEST(test_parse_jobid2); } diff --git a/src/lib/utils.c b/src/lib/utils.c index 43123b2..e1deef0 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -15,6 +15,7 @@ #include #endif +#include #include #include "config.h" @@ -409,3 +410,110 @@ void free_strlist(xce_strlist_t* l) FREEUP(l->data); } + +int fmt_jobid(char* buf, size_t sz, uint64_t jobid) +{ + uint32_t tag, id_cluster, id_apiserver, id_timestamp; + char data[128]; + int len = 0; + + tag = EXTRACT_ID_TAG(jobid); + id_cluster = EXTRACT_ID_CLUSTER(jobid); + id_apiserver = EXTRACT_ID_APISERVER(jobid); + id_timestamp = EXTRACT_ID_TIMESTAMP(jobid); + + memset(data, 0x0, sizeof(data)); + + if ((tag & TAG_JOB_ARRAY) != 0) { + uint32_t id_job, id_idx; + + id_job = EXTRACT_ARRAY_JOB(jobid); + id_idx = EXTRACT_ARRAY_IDX(jobid); + + snprintf(data, sizeof(data) - 1, "%d-%d-%d-%d[%d]", id_cluster, + id_apiserver, id_timestamp, id_job, id_idx); + } else { + uint32_t id_seq; + + id_seq = EXTRACT_ID_SEQUENCE(jobid); + snprintf(data, sizeof(data) - 1, "%d-%d-%d-%d", id_cluster, + id_apiserver, id_timestamp, id_seq); + } + + len = strlen(data); + if (len > sz - 1) { + return -1; + } + + strncpy(buf, data, sz); + return len; +} + +int parse_jobid(uint64_t* jobid, char* buf) +{ + regex_t regex; + regmatch_t pmatch[N_MAX_FIELDS_JOBID + 1]; + int rc; + int len = strlen(buf); + + if ((jobid == NULL) || (buf == NULL)) { + return -EINVAL; + } + + rc = regcomp(®ex, REGEX_JOBARRAY_ID, REG_EXTENDED); + if (rc != 0) { + return -errno; + } + + *jobid = 0; + rc = regexec(®ex, buf, N_EL_ARRAY(pmatch), pmatch, 0); + if (rc == 0) { + regfree(®ex); + + if ((pmatch[0].rm_so == 0) && (pmatch[0].rm_eo == len)) { + uint32_t tag, id_cluster, id_apiserver, id_timestamp, id_job, + id_idx; + + tag = 0x01; /* job array */ + id_cluster = atoi(&buf[pmatch[1].rm_so]); + id_apiserver = atoi(&buf[pmatch[2].rm_so]); + id_timestamp = atoi(&buf[pmatch[3].rm_so]); + id_job = atoi(&buf[pmatch[4].rm_so]); + id_idx = atoi(&buf[pmatch[5].rm_so]); + + *jobid = MAKE_JOBID(id_cluster, id_apiserver, id_timestamp, tag, + id_job + id_idx); + return 1; + } + } + + regfree(®ex); + rc = regcomp(®ex, REGEX_JOBID, REG_EXTENDED); + if (rc != 0) { + return -errno; + } + + rc = regexec(®ex, buf, N_EL_ARRAY(pmatch), pmatch, 0); + if (rc == 0) { + uint32_t id_cluster, id_apiserver, id_timestamp, id_job; + + if ((pmatch[0].rm_so != 0) || (pmatch[0].rm_eo != len)) { + regfree(®ex); + return -EINVAL; + } + + id_cluster = atoi(&buf[pmatch[1].rm_so]); + id_apiserver = atoi(&buf[pmatch[2].rm_so]); + id_timestamp = atoi(&buf[pmatch[3].rm_so]); + id_job = atoi(&buf[pmatch[4].rm_so]); + + *jobid + = MAKE_JOBID(id_cluster, id_apiserver, id_timestamp, 0x0, id_job); + + regfree(®ex); + return 1; + } + + regfree(®ex); + return -EINVAL; +} diff --git a/src/meson.build b/src/meson.build index db12ddf..2396118 100644 --- a/src/meson.build +++ b/src/meson.build @@ -3,18 +3,22 @@ project('xce', version: '0.0.1', meson_version: '>=1.5', default_options: [ - 'c_std=gnu17', - 'c_args=-DDEBUG -g -ggdb']) + 'c_std=gnu17']) with_debug=false if get_option('buildtype') == 'debug' # add -DWITH_DEBUG=1 - add_project_arguments('-DWITH_DEBUG=1', language: 'c') - add_project_arguments('-Wno-cpp', language: ['c', 'cpp']) - # add_project_arguments('-Og', language: 'c') - add_project_arguments('-fno-inline', language: 'c') - add_project_arguments('-fno-omit-frame-pointer', language: 'c') + add_project_arguments(['-DWITH_DEBUG=1', + '-DDEBUG', + '-Wno-cpp', + '-fno-inline', + '-fno-omit-frame-pointer', + '-ggdb', + '-g3', + '-fvar-tracking', + '-fvar-tracking-assignments', + ], language: ['c', 'cpp']) with_debug=true endif