Line data Source code
1 : /*
2 : * libpoporon - erasure.c
3 : *
4 : * Copyright (c) 2025 Go Kudo
5 : *
6 : * This library is licensed under the BSD 3-Clause License.
7 : * For license details, please refer to the LICENSE file.
8 : *
9 : * SPDX-FileCopyrightText: Go Kudo <zeriyoshi@gmail.com>
10 : * SPDX-License-Identifier: BSD-3-Clause
11 : */
12 :
13 : #include "poporon_internal.h"
14 :
15 7 : extern void poporon_erasure_destroy(poporon_erasure_t *erasure)
16 : {
17 7 : if (erasure) {
18 6 : if (erasure->erasure_positions) {
19 6 : pfree(erasure->erasure_positions);
20 : }
21 6 : if (erasure->corrections) {
22 6 : pfree(erasure->corrections);
23 : }
24 :
25 6 : pfree(erasure);
26 : }
27 7 : }
28 :
29 6 : extern poporon_erasure_t *poporon_erasure_create(uint16_t num_roots, uint32_t initial_capacity)
30 : {
31 6 : poporon_erasure_t *erasure = NULL;
32 : uint32_t capacity;
33 :
34 6 : capacity = (initial_capacity > 0) ? initial_capacity : (uint32_t)num_roots;
35 :
36 6 : erasure = (poporon_erasure_t *)pmalloc(sizeof(poporon_erasure_t));
37 6 : if (!erasure) {
38 : return NULL; /* LCOV_EXCL_LINE */
39 : }
40 6 : erasure->erasure_positions = NULL;
41 6 : erasure->corrections = NULL;
42 :
43 6 : erasure->erasure_positions = (uint32_t *)pmalloc(capacity * sizeof(uint32_t));
44 6 : if (!erasure->erasure_positions) {
45 : /* LCOV_EXCL_START */
46 : poporon_erasure_destroy(erasure);
47 : return NULL;
48 : /* LCOV_EXCL_STOP */
49 : }
50 :
51 6 : erasure->corrections = (uint16_t *)pmalloc(capacity * sizeof(uint16_t));
52 6 : if (!erasure->corrections) {
53 : /* LCOV_EXCL_START */
54 : poporon_erasure_destroy(erasure);
55 : return NULL;
56 : /* LCOV_EXCL_STOP */
57 : }
58 :
59 6 : erasure->capacity = capacity;
60 6 : erasure->erasure_count = 0;
61 :
62 6 : return erasure;
63 : }
64 :
65 3 : extern poporon_erasure_t *poporon_erasure_create_from_positions(uint16_t num_roots, const uint32_t *erasure_positions, uint32_t erasure_count)
66 : {
67 3 : poporon_erasure_t *erasure = NULL;
68 : uint32_t capacity;
69 :
70 3 : if (!erasure_positions || erasure_count == 0) {
71 2 : return NULL;
72 : }
73 :
74 1 : capacity = (erasure_count > num_roots) ? erasure_count : num_roots;
75 :
76 1 : erasure = poporon_erasure_create(num_roots, capacity);
77 1 : if (!erasure) {
78 : return NULL; /* LCOV_EXCL_LINE */
79 : }
80 :
81 1 : pmemcpy(erasure->erasure_positions, erasure_positions, erasure_count * sizeof(uint32_t));
82 1 : erasure->erasure_count = erasure_count;
83 :
84 1 : return erasure;
85 : }
86 :
87 45 : extern bool poporon_erasure_add_position(poporon_erasure_t *erasure, uint32_t position)
88 : {
89 : uint32_t new_capacity, *new_positions;
90 : uint16_t *new_corrections;
91 :
92 45 : if (!erasure) {
93 1 : return false;
94 : }
95 :
96 44 : if (erasure->erasure_count >= erasure->capacity) {
97 1 : new_capacity = erasure->capacity * 2;
98 1 : if (new_capacity < erasure->capacity + 32) {
99 1 : new_capacity = erasure->capacity + 32;
100 : }
101 :
102 1 : new_positions = (uint32_t *)prealloc(erasure->erasure_positions, new_capacity * sizeof(uint32_t));
103 1 : new_corrections = (uint16_t *)prealloc(erasure->corrections, new_capacity * sizeof(uint16_t));
104 :
105 1 : if (!new_positions || !new_corrections) {
106 : /* LCOV_EXCL_START */
107 : if (new_positions) {
108 : pfree(new_positions);
109 : }
110 : if (new_corrections) {
111 : pfree(new_corrections);
112 : }
113 :
114 : return false;
115 : /* LCOV_EXCL_STOP */
116 : }
117 :
118 1 : erasure->erasure_positions = new_positions;
119 1 : erasure->corrections = new_corrections;
120 1 : erasure->capacity = new_capacity;
121 : }
122 :
123 44 : erasure->erasure_positions[erasure->erasure_count++] = position;
124 :
125 44 : return true;
126 : }
127 :
128 2 : extern void poporon_erasure_reset(poporon_erasure_t *erasure)
129 : {
130 2 : if (erasure) {
131 1 : erasure->erasure_count = 0;
132 : }
133 2 : }
|