Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "bincopydata.h"
14 :
15 : static const copy_binary_timestamp binary_nil_timestamp = {
16 : .time = {
17 : .ms = 0xFFFFFFFF,
18 : .seconds = 255,
19 : .minutes = 255,
20 : .hours = 255,
21 : .padding = 255,
22 : },
23 : .date = {
24 : .day = 255,
25 : .month = 255,
26 : .year =-1,
27 : },
28 : };
29 :
30 : static copy_binary_timestamp
31 10000000 : random_timestamp(struct rng *rng)
32 : {
33 10000000 : copy_binary_timestamp ts;
34 10000000 : if (rng_next(rng) % 10 == 9) {
35 997010 : ts = binary_nil_timestamp;
36 997010 : return ts;
37 : }
38 :
39 : // the % trick gives a little skew but we don't care
40 9002990 : ts = (copy_binary_timestamp){
41 : .time = {
42 9002990 : .ms = rng_next(rng) % 1000000,
43 9002990 : .seconds = rng_next(rng) % 60, // 61 ??
44 9002990 : .minutes = rng_next(rng) % 60,
45 9002990 : .hours = rng_next(rng) % 24,
46 : .padding = 0,
47 : },
48 : .date = {
49 : .day = 0, // determine later
50 9002990 : .month = 1 + rng_next(rng) % 12,
51 9002990 : .year = 2030 - (int16_t)rng_next(rng) % 2300,
52 : },
53 : };
54 :
55 9002990 : const uint32_t durations[] = { 0,
56 : 31, 28, 31, 30,
57 : 31, 30, 31, 31,
58 : 30, 31, 30, 31,
59 : };
60 9002990 : int16_t year = ts.date.year;
61 9002990 : uint32_t days = durations[ts.date.month];
62 9002990 : bool leap_year = (
63 9002990 : days == 28 &&
64 9002990 : year > 0 && year % 4 == 0 &&
65 176770 : (year % 100 != 0 || year % 400 == 0)
66 : );
67 : if (leap_year)
68 : days = 29;
69 9002990 : ts.date.day = 1 + rng_next(rng) % days;
70 :
71 9002990 : return ts;
72 : }
73 :
74 : void
75 1 : gen_timestamps(FILE *f, bool byteswap, long nrecs, char *arg)
76 : {
77 1 : (void)arg;
78 1 : struct rng rng = my_favorite_rng();
79 :
80 1000001 : for (long i = 0; i < nrecs; i++) {
81 1000000 : copy_binary_timestamp ts = random_timestamp(&rng);
82 1000000 : if (byteswap) {
83 0 : copy_binary_convert_timestamp(&ts);
84 : }
85 1000000 : fwrite(&ts, sizeof(ts), 1, f);
86 : }
87 1 : }
88 :
89 : #define GEN_TIMESTAMP_FIELD(name, typ, fld, nilvalue) \
90 : void name \
91 : (FILE *f, bool byteswap, long nrecs, char *arg) \
92 : { \
93 : (void)arg; \
94 : struct rng rng = my_favorite_rng(); \
95 : \
96 : for (long i = 0; i < nrecs; i++) { \
97 : copy_binary_timestamp ts = random_timestamp(&rng); \
98 : typ *p = &ts.fld; \
99 : typ tmp = ts.date.day == 255 ? nilvalue : *p; \
100 : if (byteswap) { \
101 : copy_binary_convert_timestamp(&ts); \
102 : } \
103 : fwrite(&tmp, sizeof(tmp), 1, f); \
104 : } \
105 : }
106 :
107 1000001 : GEN_TIMESTAMP_FIELD(gen_timestamp_times, copy_binary_time, time, binary_nil_timestamp.time)
108 1000001 : GEN_TIMESTAMP_FIELD(gen_timestamp_dates, copy_binary_date, date, binary_nil_timestamp.date)
109 :
110 1000001 : GEN_TIMESTAMP_FIELD(gen_timestamp_ms, uint32_t, time.ms, 0x80)
111 1000001 : GEN_TIMESTAMP_FIELD(gen_timestamp_seconds, uint8_t, time.seconds, 0x80)
112 1000001 : GEN_TIMESTAMP_FIELD(gen_timestamp_minutes, uint8_t, time.minutes, 0x80)
113 1000001 : GEN_TIMESTAMP_FIELD(gen_timestamp_hours, uint8_t, time.hours, 0x80)
114 1000001 : GEN_TIMESTAMP_FIELD(gen_timestamp_days, uint8_t, date.day, 0x80)
115 1000001 : GEN_TIMESTAMP_FIELD(gen_timestamp_months, uint8_t, date.month, 0x80)
116 1000001 : GEN_TIMESTAMP_FIELD(gen_timestamp_years, int16_t, date.year, -1)
|