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