diff options
Diffstat (limited to 'qpid/cpp/src/qpid/linearstore/journal/utils')
12 files changed, 857 insertions, 0 deletions
diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/deq_hdr.c b/qpid/cpp/src/qpid/linearstore/journal/utils/deq_hdr.c new file mode 100644 index 0000000000..b55c1c16c8 --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/deq_hdr.c @@ -0,0 +1,46 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "deq_hdr.h" + +/*static const uint16_t DEQ_HDR_TXNCMPLCOMMIT_MASK = 0x10;*/ + +void deq_hdr_init(deq_hdr_t* dest, const uint32_t magic, const uint16_t version, const uint16_t uflag, + const uint64_t serial, const uint64_t rid, const uint64_t deq_rid, const uint64_t xidsize) { + rec_hdr_init(&dest->_rhdr, magic, version, uflag, serial, rid); + dest->_deq_rid = deq_rid; + dest->_xidsize = xidsize; +} + +void deq_hdr_copy(deq_hdr_t* dest, const deq_hdr_t* src) { + rec_hdr_copy(&dest->_rhdr, &src->_rhdr); + dest->_deq_rid = src->_deq_rid; + dest->_xidsize = src->_xidsize; +} + +bool is_txn_coml_commit(const deq_hdr_t *dh) { + return dh->_rhdr._uflag & DEQ_HDR_TXNCMPLCOMMIT_MASK; +} + +void set_txn_coml_commit(deq_hdr_t *dh, const bool commit) { + dh->_rhdr._uflag = commit ? dh->_rhdr._uflag | DEQ_HDR_TXNCMPLCOMMIT_MASK : // set flag bit + dh->_rhdr._uflag & (~DEQ_HDR_TXNCMPLCOMMIT_MASK); // unset flag bit +} diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/deq_hdr.h b/qpid/cpp/src/qpid/linearstore/journal/utils/deq_hdr.h new file mode 100644 index 0000000000..3392867153 --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/deq_hdr.h @@ -0,0 +1,83 @@ +#ifndef QPID_LINEARSTORE_JOURNAL_UTILS_DEQ_HDR_H +#define QPID_LINEARSTORE_JOURNAL_UTILS_DEQ_HDR_H +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include <stdbool.h> +#include "rec_hdr.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#pragma pack(1) + +/** + * \brief Struct for dequeue record. + * + * Struct for dequeue record. If this record has a non-zero xidsize field (i.e., there is a + * valid XID), then this header is followed by the XID of xidsize bytes and a rec_tail. If, + * on the other hand, this record has a zero xidsize (i.e., there is no XID), then the rec_tail + * is absent. + * + * Note that this record had its own rid distinct from the rid of the record it is dequeueing. + * The rid field below is the rid of the dequeue record itself; the deq-rid field is the rid of a + * previous enqueue record being dequeued by this record. + * + * Record header info in binary format (40 bytes): + * <pre> + * 0 7 + * +---+---+---+---+---+---+---+---+ -+ + * | magic | ver | flags | | + * +---+---+---+---+---+---+---+---+ | + * | serial | | struct rec_hdr_t + * +---+---+---+---+---+---+---+---+ | + * | rid | | + * +---+---+---+---+---+---+---+---+ -+ + * | deq-rid | + * +---+---+---+---+---+---+---+---+ + * | xidsize | + * +---+---+---+---+---+---+---+---+ + * + * deq-rid = dequeue record ID + * </pre> + */ +typedef struct deq_hdr_t { + rec_hdr_t _rhdr; /**< Common record header struct */ + uint64_t _deq_rid; /**< Record ID of record being dequeued */ + uint64_t _xidsize; /**< XID size */ +} deq_hdr_t; + +static const uint16_t DEQ_HDR_TXNCMPLCOMMIT_MASK = 0x10; + +void deq_hdr_init(deq_hdr_t* dest, const uint32_t magic, const uint16_t version, const uint16_t uflag, + const uint64_t serial, const uint64_t rid, const uint64_t deq_rid, const uint64_t xidsize); +void deq_hdr_copy(deq_hdr_t* dest, const deq_hdr_t* src); +bool is_txn_coml_commit(const deq_hdr_t *dh); +void set_txn_coml_commit(deq_hdr_t *dh, const bool commit); + +#pragma pack() + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef QPID_LINEARSTORE_JOURNAL_UTILS_DEQ_HDR_H */ diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/enq_hdr.c b/qpid/cpp/src/qpid/linearstore/journal/utils/enq_hdr.c new file mode 100644 index 0000000000..b4e8b62ff1 --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/enq_hdr.c @@ -0,0 +1,63 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "enq_hdr.h" + +//static const uint16_t ENQ_HDR_TRANSIENT_MASK = 0x10; +//static const uint16_t ENQ_HDR_EXTERNAL_MASK = 0x20; + +void enq_hdr_init(enq_hdr_t* dest, const uint32_t magic, const uint16_t version, const uint16_t uflag, + const uint64_t serial, const uint64_t rid, const uint64_t xidsize, const uint64_t dsize) { + rec_hdr_init(&dest->_rhdr, magic, version, uflag, serial, rid); + dest->_xidsize = xidsize; + dest->_dsize = dsize; +} + +void enq_hdr_copy(enq_hdr_t* dest, const enq_hdr_t* src) { + rec_hdr_copy(&dest->_rhdr, &src->_rhdr); + dest->_xidsize = src->_xidsize; + dest->_dsize = src->_dsize; +} + +bool is_enq_transient(const enq_hdr_t *eh) { + return eh->_rhdr._uflag & ENQ_HDR_TRANSIENT_MASK; +} + +void set_enq_transient(enq_hdr_t *eh, const bool transient) { + eh->_rhdr._uflag = transient ? eh->_rhdr._uflag | ENQ_HDR_TRANSIENT_MASK : + eh->_rhdr._uflag & (~ENQ_HDR_TRANSIENT_MASK); +} + +bool is_enq_external(const enq_hdr_t *eh) { + return eh->_rhdr._uflag & ENQ_HDR_EXTERNAL_MASK; +} + +void set_enq_external(enq_hdr_t *eh, const bool external) { + eh->_rhdr._uflag = external ? eh->_rhdr._uflag | ENQ_HDR_EXTERNAL_MASK : + eh->_rhdr._uflag & (~ENQ_HDR_EXTERNAL_MASK); +} + +bool validate_enq_hdr(enq_hdr_t *eh, const uint32_t magic, const uint16_t version, const uint64_t rid) { + return eh->_rhdr._magic == magic && + eh->_rhdr._version == version && + rid > 0 ? eh->_rhdr._rid == rid /* If rid == 0, don't compare rids */ + : true; +} diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/enq_hdr.h b/qpid/cpp/src/qpid/linearstore/journal/utils/enq_hdr.h new file mode 100644 index 0000000000..00108792bc --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/enq_hdr.h @@ -0,0 +1,83 @@ +#ifndef QPID_LINEARSTORE_JOURNAL_UTILS_ENQ_HDR_H +#define QPID_LINEARSTORE_JOURNAL_UTILS_ENQ_HDR_H +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include <stdbool.h> +#include "rec_hdr.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#pragma pack(1) + +/** + * \brief Struct for enqueue record. + * + * Struct for enqueue record. In addition to the common data, this header includes both the + * xid and data blob sizes. + * + * This header precedes all enqueue data in journal files. + * + * Record header info in binary format (40 bytes): + * <pre> + * 0 7 + * +---+---+---+---+---+---+---+---+ -+ + * | magic | ver | flags | | + * +---+---+---+---+---+---+---+---+ | + * | serial | | struct rec_hdr_t + * +---+---+---+---+---+---+---+---+ | + * | rid | | + * +---+---+---+---+---+---+---+---+ -+ + * | xidsize | + * +---+---+---+---+---+---+---+---+ + * | dsize | + * +---+---+---+---+---+---+---+---+ + * v = file version (If the format or encoding of this file changes, then this + * number should be incremented) + * </pre> + */ +typedef struct enq_hdr_t { + rec_hdr_t _rhdr; /**< Common record header struct */ + uint64_t _xidsize; /**< XID size in octets */ + uint64_t _dsize; /**< Record data size in octets */ +} enq_hdr_t; + +static const uint16_t ENQ_HDR_TRANSIENT_MASK = 0x10; +static const uint16_t ENQ_HDR_EXTERNAL_MASK = 0x20; + +void enq_hdr_init(enq_hdr_t* dest, const uint32_t magic, const uint16_t version, const uint16_t uflag, + const uint64_t serial, const uint64_t rid, const uint64_t xidsize, const uint64_t dsize); +void enq_hdr_copy(enq_hdr_t* dest, const enq_hdr_t* src); +bool is_enq_transient(const enq_hdr_t *eh); +void set_enq_transient(enq_hdr_t *eh, const bool transient); +bool is_enq_external(const enq_hdr_t *eh); +void set_enq_external(enq_hdr_t *eh, const bool external); +bool validate_enq_hdr(enq_hdr_t *eh, const uint32_t magic, const uint16_t version, const uint64_t rid); + +#pragma pack() + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef QPID_LINEARSTORE_JOURNAL_UTILS_ENQ_HDR_H */ diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.c b/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.c new file mode 100644 index 0000000000..4e6cf1b8fa --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.c @@ -0,0 +1,115 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "file_hdr.h" +#include <string.h> + +void file_hdr_create(file_hdr_t* dest, const uint32_t magic, const uint16_t version, const uint16_t fhdr_size_sblks, + const uint16_t efp_partition, const uint64_t file_size) { + rec_hdr_init(&dest->_rhdr, magic, version, 0, 0, 0); + dest->_fhdr_size_sblks = fhdr_size_sblks; + dest->_efp_partition = efp_partition; + dest->_reserved = 0; + dest->_data_size_kib = file_size; + dest->_fro = 0; + dest->_ts_nsec = 0; + dest->_ts_sec = 0; + dest->_file_number = 0; + dest->_queue_name_len = 0; +} + +int file_hdr_init(void* dest, const uint64_t dest_len, const uint16_t uflag, const uint64_t serial, const uint64_t rid, + const uint64_t fro, const uint64_t file_number, const uint16_t queue_name_len, const char* queue_name) { + file_hdr_t* fhp = (file_hdr_t*)dest; + fhp->_rhdr._uflag = uflag; + fhp->_rhdr._serial = serial; + fhp->_rhdr._rid = rid; + fhp->_fro = fro; + fhp->_file_number = file_number; + if (sizeof(file_hdr_t) + queue_name_len < MAX_FILE_HDR_LEN) { + fhp->_queue_name_len = queue_name_len; + } else { + fhp->_queue_name_len = MAX_FILE_HDR_LEN - sizeof(file_hdr_t); + } + fhp->_queue_name_len = queue_name_len; + memcpy((char*)dest + sizeof(file_hdr_t), queue_name, queue_name_len); + memset((char*)dest + sizeof(file_hdr_t) + queue_name_len, 0, dest_len - sizeof(file_hdr_t) - queue_name_len); + return set_time_now(dest); +} + +int file_hdr_check(file_hdr_t* hdr, const uint32_t magic, const uint16_t version, const uint64_t data_size_kib, const uint16_t max_queue_name_len) { + int err = rec_hdr_check_base(&hdr->_rhdr, magic, version); + if (data_size_kib && hdr->_data_size_kib != data_size_kib) err |= 0x1000; + if (hdr->_queue_name_len > max_queue_name_len) err |= 0x10000; + return err; +} + +void file_hdr_copy(file_hdr_t* dest, const file_hdr_t* src) { + rec_hdr_copy(&dest->_rhdr, &src->_rhdr); + dest->_fhdr_size_sblks = src->_fhdr_size_sblks; // Should this be copied? + dest->_efp_partition = src->_efp_partition; // Should this be copied? + dest->_data_size_kib = src->_data_size_kib; + dest->_fro = src->_fro; + dest->_ts_sec = src->_ts_sec; + dest->_ts_nsec = src->_ts_nsec; + dest->_file_number = src->_file_number; +} + +void file_hdr_reset(file_hdr_t* target) { + target->_rhdr._uflag = 0; + target->_rhdr._serial = 0; + target->_rhdr._rid = 0; + target->_fro = 0; + target->_ts_sec = 0; + target->_ts_nsec = 0; + target->_file_number = 0; + target->_queue_name_len = 0; +} + +int is_file_hdr_reset(file_hdr_t* target) { + return target->_rhdr._uflag == 0 && + target->_rhdr._serial == 0 && + target->_rhdr._rid == 0 && + target->_ts_sec == 0 && + target->_ts_nsec == 0 && + target->_file_number == 0 && + target->_queue_name_len == 0; +} + +int set_time_now(file_hdr_t *fh) +{ + struct timespec ts; + int err = clock_gettime(CLOCK_REALTIME, &ts); + if (err) + return err; + fh->_ts_sec = ts.tv_sec; + fh->_ts_nsec = ts.tv_nsec; + return 0; +} + + +void set_time(file_hdr_t *fh, struct timespec *ts) +{ + fh->_ts_sec = ts->tv_sec; + fh->_ts_nsec = ts->tv_nsec; +} + + diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.h b/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.h new file mode 100644 index 0000000000..5987e1871e --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/file_hdr.h @@ -0,0 +1,111 @@ +#ifndef QPID_LINEARSTORE_JOURNAL_UTILS_FILE_HDR_H +#define QPID_LINEARSTORE_JOURNAL_UTILS_FILE_HDR_H +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include <time.h> +#include "rec_hdr.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#define MAX_FILE_HDR_LEN 4096 // Set to 1 sblk + +#pragma pack(1) + +/** + * \brief Struct for data common to the head of all journal files. In addition to + * the common data, this includes the record ID and offset of the first record in + * the file. + * + * This header precedes all data in journal files and occupies the first complete + * block in the file. The record ID and offset are updated on each overwrite of the + * file. + * + * File header info in binary format (74 bytes + size of file name in octets): + * <pre> + * 0 7 + * +---+---+---+---+---+---+---+---+ -+ + * | magic | ver | flags | | + * +---+---+---+---+---+---+---+---+ | + * | serial | | struct rec_hdr_t + * +---+---+---+---+---+---+---+---+ | + * | rid | | + * +---+---+---+---+---+---+---+---+ -+ + * | fhs | partn | reserved | + * +---+---+---+---+---+---+---+---+ + * | data-size | + * +---+---+---+---+---+---+---+---+ + * | fro | + * +---+---+---+---+---+---+---+---+ + * | timestamp (sec) | + * +---+---+---+---+---+---+---+---+ + * | timestamp (ns) | + * +---+---+---+---+---+---+---+---+ + * | file-number | + * +---+---+---+---+---+---+---+---+ + * | qnl | Queue Name... | + * +-------+ | + * | | + * +---+---+---+---+---+---+---+---+ + * + * ver = Journal version + * rid = Record ID + * fhs = File header size in sblks (defined by JRNL_SBLK_SIZE) + * partn = EFP partition from which this file came + * fro = First Record Offset + * qnl = Length of the queue name in octets. + * </pre> + */ +typedef struct file_hdr_t { + rec_hdr_t _rhdr; /**< Common record header struct, but rid field is used for rid of first compete record in file */ + uint16_t _fhdr_size_sblks; /**< File header size in sblks (defined by JRNL_SBLK_SIZE) */ + uint16_t _efp_partition; /**< EFP Partition number from which this file was obtained */ + uint32_t _reserved; + uint64_t _data_size_kib; /**< Size of the data part of this file in KiB. (ie file size excluding file header sblk) */ + uint64_t _fro; /**< First Record Offset (FRO) */ + uint64_t _ts_sec; /**< Time stamp (seconds part) */ + uint64_t _ts_nsec; /**< Time stamp (nanoseconds part) */ + uint64_t _file_number; /**< The logical number of this file in a monotonically increasing sequence */ + uint16_t _queue_name_len; /**< Length of the queue name in octets, which follows this struct in the header */ +} file_hdr_t; + +void file_hdr_create(file_hdr_t* dest, const uint32_t magic, const uint16_t version, + const uint16_t fhdr_size_sblks, const uint16_t efp_partition, const uint64_t file_size); +int file_hdr_init(void* dest, const uint64_t dest_len, const uint16_t uflag, const uint64_t serial, const uint64_t rid, + const uint64_t fro, const uint64_t file_number, const uint16_t queue_name_len, + const char* queue_name); +int file_hdr_check(file_hdr_t* hdr, const uint32_t magic, const uint16_t version, const uint64_t data_size_kib, + const uint16_t max_queue_name_len); +void file_hdr_reset(file_hdr_t* target); +int is_file_hdr_reset(file_hdr_t* target); +void file_hdr_copy(file_hdr_t* dest, const file_hdr_t* src); +int set_time_now(file_hdr_t *fh); +void set_time(file_hdr_t *fh, struct timespec *ts); + +#pragma pack() + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef QPID_LINEARSTORE_JOURNAL_UTILS_FILE_HDR_H */ diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.c b/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.c new file mode 100644 index 0000000000..32eda8de5a --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.c @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "rec_hdr.h" + +void rec_hdr_init(rec_hdr_t* dest, const uint32_t magic, const uint16_t version, const uint16_t uflag, const uint64_t serial, const uint64_t rid) { + dest->_magic = magic; + dest->_version = version; + dest->_uflag = uflag; + dest->_serial = serial; + dest->_rid = rid; +} + +void rec_hdr_copy(rec_hdr_t* dest, const rec_hdr_t* src) { + dest->_magic = src->_magic; + dest->_version = src->_version; + dest->_uflag = src->_uflag; + dest->_serial = src->_serial; + dest->_rid = src->_rid; +} + +int rec_hdr_check_base(rec_hdr_t* header, const uint32_t magic, const uint16_t version) { + int err = 0; + if (header->_magic != magic) err |= 0x1; + if (header->_version != version) err |= 0x10; + return err; +} + +int rec_hdr_check(rec_hdr_t* header, const uint32_t magic, const uint16_t version, const uint64_t serial) { + int err = rec_hdr_check_base(header, magic, version); + if (header->_serial != serial) err |= 0x100; + return err; +} diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.h b/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.h new file mode 100644 index 0000000000..64349b5ab8 --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/rec_hdr.h @@ -0,0 +1,72 @@ +#ifndef QPID_LINEARSTORE_JOURNAL_UTILS_REC_HDR_H +#define QPID_LINEARSTORE_JOURNAL_UTILS_REC_HDR_H +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C"{ +#endif + +#pragma pack(1) + +/** + * \brief Struct for data common to the head of all journal files and records. + * This includes identification for the file type, the encoding version, endian + * indicator and a record ID. + * + * File header info in binary format (24 bytes): + * <pre> + * 0 7 + * +---+---+---+---+---+---+---+---+ + * | magic | ver | uflag | + * +---+---+---+---+---+---+---+---+ + * | serial | + * +---+---+---+---+---+---+---+---+ + * | rid | + * +---+---+---+---+---+---+---+---+ + * + * ver = file version (If the format or encoding of this file changes, then this + * number should be incremented) + * rid = Record ID + * </pre> + */ +typedef struct rec_hdr_t { + uint32_t _magic; /**< File type identifier (magic number) */ + uint16_t _version; /**< File encoding version */ + uint16_t _uflag; /**< User-defined flags */ + uint64_t _serial; /**< Serial number for this journal file */ + uint64_t _rid; /**< Record ID (rotating 64-bit counter) */ +} rec_hdr_t; + +void rec_hdr_init(rec_hdr_t* dest, const uint32_t magic, const uint16_t version, const uint16_t uflag, const uint64_t serial, const uint64_t rid); +void rec_hdr_copy(rec_hdr_t* dest, const rec_hdr_t* src); +int rec_hdr_check_base(rec_hdr_t* header, const uint32_t magic, const uint16_t version); +int rec_hdr_check(rec_hdr_t* header, const uint32_t magic, const uint16_t version, const uint64_t serial); + +#pragma pack() + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef QPID_LINEARSTORE_JOURNAL_UTILS_REC_HDR_H */ diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/rec_tail.c b/qpid/cpp/src/qpid/linearstore/journal/utils/rec_tail.c new file mode 100644 index 0000000000..7128c96f32 --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/rec_tail.c @@ -0,0 +1,46 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "rec_tail.h" + +void rec_tail_init(rec_tail_t* dest, const uint32_t xmagic, const uint32_t checksum, const uint64_t serial, + const uint64_t rid) { + dest->_xmagic = xmagic; + dest->_checksum = checksum; + dest->_serial = serial; + dest->_rid = rid; +} + +void rec_tail_copy(rec_tail_t* dest, const rec_hdr_t* src, const uint32_t checksum) { + dest->_xmagic = ~(src->_magic); + dest->_checksum = checksum; + dest->_serial = src->_serial; + dest->_rid = src->_rid; +} + +uint16_t rec_tail_check(const rec_tail_t* tail, const rec_hdr_t* header, const uint32_t checksum) { + uint16_t err = 0; + if (tail->_xmagic != ~header->_magic) err |= REC_TAIL_MAGIC_ERR_MASK; + if (tail->_serial != header->_serial) err |= REC_TAIL_SERIAL_ERR_MASK; + if (tail->_rid != header->_rid) err |= REC_TAIL_RID_ERR_MASK; + if (tail->_checksum != checksum) err |= REC_TAIL_CHECKSUM_ERR_MASK; + return err; +} diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/rec_tail.h b/qpid/cpp/src/qpid/linearstore/journal/utils/rec_tail.h new file mode 100644 index 0000000000..afc71c104a --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/rec_tail.h @@ -0,0 +1,82 @@ +#ifndef QPID_LINEARSTORE_JOURNAL_UTILS_REC_TAIL_H +#define QPID_LINEARSTORE_JOURNAL_UTILS_REC_TAIL_H +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include <stdint.h> +#include "rec_hdr.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#pragma pack(1) + +/** + * \brief Struct for data common to the tail of all records. The magic number + * used here is the binary inverse (1's complement) of the magic used in the + * record header; this minimizes possible confusion with other headers that may + * be present during recovery. The tail is used with all records that have either + * XIDs or data - ie any size-variable content. Currently the only records that + * do NOT use the tail are non-transactional dequeues and filler records. + * + * The checksum is used to verify the xid and/or data portion of the record + * on recovery, and excludes the header and tail. + * + * Record header info in binary format (24 bytes): + * <pre> + * 0 7 + * +---+---+---+---+---+---+---+---+ + * | ~(magic) | checksum | + * +---+---+---+---+---+---+---+---+ + * | serial | + * +---+---+---+---+---+---+---+---+ + * | rid | + * +---+---+---+---+---+---+---+---+ + * + * ~(magic) = 1's compliment of magic of matching record header + * rid = Record ID of matching record header + * </pre> + */ +typedef struct rec_tail_t { + uint32_t _xmagic; /**< Binary inverse (1's complement) of hdr magic number */ + uint32_t _checksum; /**< Checksum of xid and data (excluding header itself) */ + uint64_t _serial; /**< Serial number for this journal file */ + uint64_t _rid; /**< Record ID (rotating 64-bit counter) */ +} rec_tail_t; + +static const uint16_t REC_TAIL_MAGIC_ERR_MASK = 0x01; +static const uint16_t REC_TAIL_SERIAL_ERR_MASK = 0x02; +static const uint16_t REC_TAIL_RID_ERR_MASK = 0x04; +static const uint16_t REC_TAIL_CHECKSUM_ERR_MASK = 0x08; + +void rec_tail_init(rec_tail_t* dest, const uint32_t xmagic, const uint32_t checksum, const uint64_t serial, + const uint64_t rid); +void rec_tail_copy(rec_tail_t* dest, const rec_hdr_t* src, const uint32_t checksum); +uint16_t rec_tail_check(const rec_tail_t* tail, const rec_hdr_t* header, const uint32_t checksum); + +#pragma pack() + +#ifdef __cplusplus +} +#endif + +#endif /* ifnedf QPID_LINEARSTORE_JOURNAL_UTILS_REC_TAIL_H */ diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/txn_hdr.c b/qpid/cpp/src/qpid/linearstore/journal/utils/txn_hdr.c new file mode 100644 index 0000000000..58d4cdebe4 --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/txn_hdr.c @@ -0,0 +1,33 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "txn_hdr.h" + +void txn_hdr_init(txn_hdr_t* dest, const uint32_t magic, const uint16_t version, const uint16_t uflag, + const uint64_t serial, const uint64_t rid, const uint64_t xidsize) { + rec_hdr_init(&dest->_rhdr, magic, version, uflag, serial, rid); + dest->_xidsize = xidsize; +} + +void txn_hdr_copy(txn_hdr_t* dest, const txn_hdr_t* src) { + rec_hdr_copy(&dest->_rhdr, &src->_rhdr); + dest->_xidsize = src->_xidsize; +} diff --git a/qpid/cpp/src/qpid/linearstore/journal/utils/txn_hdr.h b/qpid/cpp/src/qpid/linearstore/journal/utils/txn_hdr.h new file mode 100644 index 0000000000..442a1d373d --- /dev/null +++ b/qpid/cpp/src/qpid/linearstore/journal/utils/txn_hdr.h @@ -0,0 +1,72 @@ +#ifndef QPID_LINEARSTORE_JOURNAL_UTILS_TXN_HDR_H +#define QPID_LINEARSTORE_JOURNAL_UTILS_TXN_HDR_H +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "rec_hdr.h" + +#ifdef __cplusplus +extern "C"{ +#endif + +#pragma pack(1) + +/** + * \brief Struct for transaction commit and abort records. + * + * Struct for local and DTX commit and abort records. Only the magic distinguishes between them. + * Since this record must be used in the context of a valid XID, the xidsize field must not be + * zero. Immediately following this record is the XID itself which is xidsize bytes long, + * followed by a rec_tail. + * + * Note that this record had its own rid distinct from the rids of the record(s) making up the + * transaction it is committing or aborting. + * + * Record header info in binary format (32 bytes): + * <pre> + * 0 7 + * +---+---+---+---+---+---+---+---+ -+ + * | magic | ver | flags | | + * +---+---+---+---+---+---+---+---+ | + * | serial | | struct rec_hdr_t + * +---+---+---+---+---+---+---+---+ | + * | rid | | + * +---+---+---+---+---+---+---+---+ -+ + * | xidsize | + * +---+---+---+---+---+---+---+---+ + * </pre> + */ +typedef struct txn_hdr_t { + rec_hdr_t _rhdr; /**< Common record header struct */ + uint64_t _xidsize; /**< XID size */ +} txn_hdr_t; + +void txn_hdr_init(txn_hdr_t* dest, const uint32_t magic, const uint16_t version, const uint16_t uflag, + const uint64_t serial, const uint64_t rid, const uint64_t xidsize); +void txn_hdr_copy(txn_hdr_t* dest, const txn_hdr_t* src); + +#pragma pack() + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef QPID_LINEARSTORE_JOURNAL_UTILS_TXN_HDR_H */ |