-
Notifications
You must be signed in to change notification settings - Fork 0
/
dynamic_array_packed.c
156 lines (147 loc) · 6.75 KB
/
dynamic_array_packed.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
Copyright 2020 moamen abdelsattar
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __DYNAMIC_ARRAY_PACKED_C__
#define __DYNAMIC_ARRAY_PACKED_C__
#include "dynamic_array.h"
#include "dynamic_array_packed.h"
#include <string.h>
//rounding division up:
// int a = 59.0f / 4.0f + 0.5f;
// int a = (59 + 4 - 1) / 4;
// q = 1 + ((x - 1) / y); // if x != 0
//I'll use the second
void initiate_dynamic_array_P(dynamic_array* the_array , const size_t initial_number_of_elements, const size_t size_of_element_in_bytes){
//must be called each time we create a new array
the_array->size_of_element = size_of_element_in_bytes;
the_array->number_of_elements = 0;
the_array->capacity = initial_number_of_elements;
the_array->elements = malloc(initial_number_of_elements * size_of_element_in_bytes);
const div_t division = div(size_of_element_in_bytes, sizeof(int_word));
the_array->num_integers = division.quot;
the_array->num_chars = division.rem;
return;
}
void append_element_P(dynamic_array* the_array, void* type_casted_element){
const size_t num = the_array->number_of_elements;
const size_t size_element = the_array->size_of_element;
const size_t offset = num * size_element;
if (the_array->capacity == 0){
size_t new_num = (num + num/2);
size_t new_size = new_num * size_element;
the_array->elements = realloc(the_array->elements, new_size);
the_array->capacity = new_num - num;
}
memcpy(the_array->elements + offset, type_casted_element, size_element);
(the_array->capacity)--;
(the_array->number_of_elements)++;
return;
}
void append_elements_P(dynamic_array* the_array, void* type_casted_elements, const size_t num_added_elements){
const size_t num = the_array->number_of_elements;
const size_t size_element = the_array->size_of_element;
const size_t offset = num * size_element;
const size_t size_copied = num_added_elements * size_element;
if (the_array->capacity < num_added_elements){
size_t new_num = num + num_added_elements;
size_t new_size = new_num * size_element;
the_array->elements = realloc(the_array->elements, new_size);
the_array->capacity = 0;
}
else{
the_array->capacity = the_array->capacity - num_added_elements;
}
memcpy((char*)(the_array->elements) + offset, type_casted_elements, size_copied);
(the_array->number_of_elements) += num_added_elements;
return;
}
void delete_element_P(dynamic_array* the_array, const size_t index){
void* elements = the_array->elements;
const size_t new_number = the_array->number_of_elements - 1;
const size_t size_element = the_array->size_of_element;
const size_t end_size = new_number * size_element;
size_t start_size = index * size_element;
while (start_size < end_size){
memcpy((char*)(elements) + start_size, (char*)(elements) + start_size + size_element, size_element);
//moving data from integer pointer to another will be faster, but we can't guarantee that the size of element
//is devidable by sizeof(int_word)
start_size += size_element;
}
the_array->elements = realloc(elements, end_size);
the_array->capacity = 0;
the_array->number_of_elements = new_number;
return;
}
void delete_elements_P(dynamic_array* the_array, int* is_removed){
//is_removed is an integer array that indicates whether a element is going to be removed
//if the corresponding index of an element in this integer array is non-zero: the element will be removed
//otherwise (it's a zero): it will remain
void* elements = the_array->elements;
const size_t num_elements = the_array->number_of_elements;
const size_t size_element = the_array->size_of_element;
const size_t total_size = num_elements * size_element;
size_t read = 0, write = 0, num_written = 0;
while (read < total_size)
{
if(!is_removed[read]){
memcpy((char*)(elements) + write, (char*)(elements) + read, size_element);
//memory_copy_fast((char*)(elements) + write, (char*)(elements) + read, size_element);
write += size_element;
num_written++;
}
read += size_element;
}
the_array->elements = realloc(elements, num_written * size_element);
the_array->capacity = 0;
the_array->number_of_elements = num_written;
return;
}
void free_array(dynamic_array* the_array){
free(the_array->elements);
the_array->number_of_elements = 0;
the_array->capacity = 0;
return;
}
void memory_copy_general(int* dist, int* origin, size_t size_copied){
//CANCELLED: used memcpy instead of this method
//integers are fastest to deal with
const div_t division = div(size_copied, sizeof(int_word));
const size_t num_integers = division.quot;
const size_t num_chars = division.rem;
const size_t start_char = num_integers * sizeof(int_word);
const size_t end_char = num_chars + start_char;
for (size_t i = 0; i < num_integers; i++)
{
dist[i] = origin[i];
}
for (size_t i = start_char; i < end_char; i++)
{
((char*)(dist))[i] = ((char*)(origin))[i];
}
return;
}
void copy_element_dynamic_array(int* dist, int* origin, dynamic_array* the_array){
//CANCELLED: used memcpy instead of this method
const size_t num_integers = the_array->num_integers;
const size_t start_char = num_integers * sizeof(int_word);
const size_t end_char = the_array->num_chars + start_char;
for (size_t i = 0; i < num_integers; i++)
{
dist[i] = origin[i];
}
for (size_t i = start_char; i < end_char; i++)
{
((char*)(dist))[i] = ((char*)(origin))[i];
}
return;
}
#endif