File Coverage

include/horus_time.h
Criterion Covered Total %
statement 29 29 100.0
branch 1 2 50.0
condition n/a
subroutine n/a
pod n/a
total 30 31 96.7


line stmt bran cond sub pod time code
1             #ifndef HORUS_TIME_H
2             #define HORUS_TIME_H
3              
4             /*
5             * horus_time.h - Timestamp helpers for UUID generation
6             *
7             * Gregorian: 60-bit count of 100-nanosecond intervals since Oct 15, 1582
8             * Unix epoch: 48-bit milliseconds since Jan 1, 1970
9             */
10              
11             #include
12             #include
13              
14             /* Offset between UUID epoch (1582-10-15) and Unix epoch (1970-01-01)
15             * in 100-nanosecond intervals */
16             #define HORUS_UUID_EPOCH_OFFSET UINT64_C(0x01B21DD213814000)
17              
18             /* ── Gregorian timestamp (for v1, v6) ───────────────────────────── */
19              
20 237           static inline uint64_t horus_gregorian_100ns(void) {
21             #if defined(CLOCK_REALTIME) && !defined(__APPLE__)
22             /* Use clock_gettime for nanosecond resolution where available */
23             struct timespec ts;
24 237           clock_gettime(CLOCK_REALTIME, &ts);
25 237           return ((uint64_t)ts.tv_sec * 10000000ULL)
26 237           + ((uint64_t)ts.tv_nsec / 100ULL)
27 237           + HORUS_UUID_EPOCH_OFFSET;
28             #else
29             /* Fallback: gettimeofday gives microsecond resolution */
30             struct timeval tv;
31             gettimeofday(&tv, NULL);
32             return ((uint64_t)tv.tv_sec * 10000000ULL)
33             + ((uint64_t)tv.tv_usec * 10ULL)
34             + HORUS_UUID_EPOCH_OFFSET;
35             #endif
36             }
37              
38             /* ── Unix epoch milliseconds (for v7) ──────────────────────────── */
39              
40 2163           static inline uint64_t horus_unix_epoch_ms(void) {
41             struct timeval tv;
42 2163           gettimeofday(&tv, NULL);
43 2163           return ((uint64_t)tv.tv_sec * 1000ULL) + ((uint64_t)tv.tv_usec / 1000ULL);
44             }
45              
46             /* ── Extract Gregorian timestamp from v1 UUID bytes ─────────────── */
47              
48 2           static inline uint64_t horus_extract_time_v1(const unsigned char *bytes) {
49             /* v1 layout: time_low (bytes 0-3), time_mid (bytes 4-5),
50             * time_hi_and_version (bytes 6-7, version in high nibble) */
51 2           uint64_t time_low = ((uint64_t)bytes[0] << 24) | ((uint64_t)bytes[1] << 16)
52 2           | ((uint64_t)bytes[2] << 8) | (uint64_t)bytes[3];
53 2           uint64_t time_mid = ((uint64_t)bytes[4] << 8) | (uint64_t)bytes[5];
54 2           uint64_t time_hi = ((uint64_t)(bytes[6] & 0x0F) << 8) | (uint64_t)bytes[7];
55              
56 2           return (time_hi << 48) | (time_mid << 32) | time_low;
57             }
58              
59             /* ── Extract Gregorian timestamp from v6 UUID bytes ─────────────── */
60              
61 1           static inline uint64_t horus_extract_time_v6(const unsigned char *bytes) {
62             /* v6 layout: time_high (bytes 0-3), time_mid (bytes 4-5),
63             * time_low_and_version (bytes 6-7, version in high nibble of byte 6) */
64 1           uint64_t time_high = ((uint64_t)bytes[0] << 24) | ((uint64_t)bytes[1] << 16)
65 1           | ((uint64_t)bytes[2] << 8) | (uint64_t)bytes[3];
66 1           uint64_t time_mid = ((uint64_t)bytes[4] << 8) | (uint64_t)bytes[5];
67 1           uint64_t time_low = ((uint64_t)(bytes[6] & 0x0F) << 8) | (uint64_t)bytes[7];
68              
69 1           return (time_high << 28) | (time_mid << 12) | time_low;
70             }
71              
72             /* ── Extract Unix epoch ms from v7 UUID bytes ───────────────────── */
73              
74 2           static inline uint64_t horus_extract_time_v7(const unsigned char *bytes) {
75             /* v7 layout: 48-bit Unix ms timestamp in bytes 0-5 */
76 2           return ((uint64_t)bytes[0] << 40) | ((uint64_t)bytes[1] << 32)
77 2           | ((uint64_t)bytes[2] << 24) | ((uint64_t)bytes[3] << 16)
78 2           | ((uint64_t)bytes[4] << 8) | (uint64_t)bytes[5];
79             }
80              
81             /* ── Convert Gregorian 100ns ticks to Unix epoch seconds (NV) ──── */
82              
83 3           static inline double horus_gregorian_to_unix(uint64_t ticks) {
84 3 50         if (ticks < HORUS_UUID_EPOCH_OFFSET) return 0.0;
85 3           return (double)(ticks - HORUS_UUID_EPOCH_OFFSET) / 10000000.0;
86             }
87              
88             /* ── Convert Unix epoch ms to Unix epoch seconds (NV) ──────────── */
89              
90 2           static inline double horus_ms_to_unix(uint64_t ms) {
91 2           return (double)ms / 1000.0;
92             }
93              
94             #endif /* HORUS_TIME_H */