Vector.c 6.22 KB
Newer Older
Hisham Muhammad's avatar
Hisham Muhammad committed
1
2
3
4
5
6
7
/*
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/

8
#include "Vector.h"
Hisham Muhammad's avatar
Hisham Muhammad committed
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "Object.h"
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#include "debug.h"
#include <assert.h>

/*{

#ifndef DEFAULT_SIZE
#define DEFAULT_SIZE -1
#endif

23
typedef void(*Vector_procedure)(void*);
Hisham Muhammad's avatar
Hisham Muhammad committed
24

25
typedef struct Vector_ {
Hisham Muhammad's avatar
Hisham Muhammad committed
26
27
28
29
30
31
   Object **array;
   int arraySize;
   int growthRate;
   int items;
   char* vectorType;
   bool owner;
32
} Vector;
Hisham Muhammad's avatar
Hisham Muhammad committed
33
34
35

}*/

36
37
Vector* Vector_new(char* vectorType_, bool owner, int size) {
   Vector* this;
Hisham Muhammad's avatar
Hisham Muhammad committed
38
39
40

   if (size == DEFAULT_SIZE)
      size = 10;
41
   this = (Vector*) malloc(sizeof(Vector));
Hisham Muhammad's avatar
Hisham Muhammad committed
42
43
44
45
46
47
48
49
50
   this->growthRate = size;
   this->array = (Object**) calloc(size, sizeof(Object*));
   this->arraySize = size;
   this->items = 0;
   this->vectorType = vectorType_;
   this->owner = owner;
   return this;
}

51
void Vector_delete(Vector* this) {
Hisham Muhammad's avatar
Hisham Muhammad committed
52
53
54
55
56
57
58
59
60
61
   if (this->owner) {
      for (int i = 0; i < this->items; i++)
         if (this->array[i])
            (this->array[i])->delete(this->array[i]);
   }
   free(this->array);
   free(this);
}

/* private */
62
bool Vector_isConsistent(Vector* this) {
Hisham Muhammad's avatar
Hisham Muhammad committed
63
64
65
66
67
68
69
70
71
72
   if (this->owner) {
      for (int i = 0; i < this->items; i++)
         if (this->array[i] && this->array[i]->class != this->vectorType)
            return false;
      return true;
   } else {
      return true;
   }
}

73
74
void Vector_prune(Vector* this) {
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
75
76
77
78
79
80
81
82
83
84
85
   int i;

   for (i = 0; i < this->items; i++)
      if (this->array[i]) {
         if (this->owner)
            (this->array[i])->delete(this->array[i]);
         this->array[i] = NULL;
      }
   this->items = 0;
}

86
87
void Vector_sort(Vector* this) {
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
88
89
90
91
92
93
94
   int i, j;
   for (i = 1; i < this->items; i++) {
      void* t = this->array[i];
      for (j = i-1; j >= 0 && this->array[j]->compare(this->array[j], t) < 0; j--)
         this->array[j+1] = this->array[j];
      this->array[j+1] = t;
   }
95
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

   /*
   for (int i = 0; i < this->items; i++) {
      for (int j = i+1; j < this->items; j++) {
         if (this->array[j]->compare(this->array[j], t) < 0) {
            void* tmp = this->array[i];
            this->array[i] = this->array[j];
            this->array[j] = tmp;
         }
      }
   }
   */
}

/* private */
111
112
void Vector_checkArraySize(Vector* this) {
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
113
114
115
116
117
118
119
120
   if (this->items >= this->arraySize) {
      int i;
      i = this->arraySize;
      this->arraySize = this->items + this->growthRate;
      this->array = (Object**) realloc(this->array, sizeof(Object*) * this->arraySize);
      for (; i < this->arraySize; i++)
         this->array[i] = NULL;
   }
121
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
122
123
}

124
void Vector_insert(Vector* this, int index, void* data_) {
Hisham Muhammad's avatar
Hisham Muhammad committed
125
126
127
   assert(index >= 0);
   assert(((Object*)data_)->class == this->vectorType);
   Object* data = data_;
128
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
129
   
130
   Vector_checkArraySize(this);
Hisham Muhammad's avatar
Hisham Muhammad committed
131
132
133
134
135
136
   assert(this->array[this->items] == NULL);
   for (int i = this->items; i >= index; i--) {
      this->array[i+1] = this->array[i];
   }
   this->array[index] = data;
   this->items++;
137
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
138
139
}

140
Object* Vector_take(Vector* this, int index) {
Hisham Muhammad's avatar
Hisham Muhammad committed
141
   assert(index >= 0 && index < this->items);
142
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
143
144
145
146
147
148
   Object* removed = this->array[index];
   assert (removed != NULL);
   this->items--;
   for (int i = index; i < this->items; i++)
      this->array[i] = this->array[i+1];
   this->array[this->items] = NULL;
149
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
150
151
152
   return removed;
}

153
154
Object* Vector_remove(Vector* this, int index) {
   Object* removed = Vector_take(this, index);
Hisham Muhammad's avatar
Hisham Muhammad committed
155
156
157
158
159
160
161
   if (this->owner) {
      removed->delete(removed);
      return NULL;
   } else
      return removed;
}

162
void Vector_moveUp(Vector* this, int index) {
Hisham Muhammad's avatar
Hisham Muhammad committed
163
   assert(index >= 0 && index < this->items);
164
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
165
166
167
168
169
170
171
   if (index == 0)
      return;
   Object* temp = this->array[index];
   this->array[index] = this->array[index - 1];
   this->array[index - 1] = temp;
}

172
void Vector_moveDown(Vector* this, int index) {
Hisham Muhammad's avatar
Hisham Muhammad committed
173
   assert(index >= 0 && index < this->items);
174
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
175
176
177
178
179
180
181
   if (index == this->items - 1)
      return;
   Object* temp = this->array[index];
   this->array[index] = this->array[index + 1];
   this->array[index + 1] = temp;
}

182
void Vector_set(Vector* this, int index, void* data_) {
Hisham Muhammad's avatar
Hisham Muhammad committed
183
184
185
   assert(index >= 0);
   assert(((Object*)data_)->class == this->vectorType);
   Object* data = data_;
186
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
187

188
   Vector_checkArraySize(this);
Hisham Muhammad's avatar
Hisham Muhammad committed
189
190
191
192
193
194
195
196
197
198
199
200
   if (index >= this->items) {
      this->items = index+1;
   } else {
      if (this->owner) {
         Object* removed = this->array[index];
         assert (removed != NULL);
         if (this->owner) {
            removed->delete(removed);
         }
      }
   }
   this->array[index] = data;
201
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
202
203
}

204
inline Object* Vector_get(Vector* this, int index) {
Hisham Muhammad's avatar
Hisham Muhammad committed
205
   assert(index < this->items);
206
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
207
208
209
   return this->array[index];
}

210
211
inline int Vector_size(Vector* this) {
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
212
213
214
   return this->items;
}

215
void Vector_merge(Vector* this, Vector* v2) {
Hisham Muhammad's avatar
Hisham Muhammad committed
216
   int i;
217
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
218
219
   
   for (i = 0; i < v2->items; i++)
220
      Vector_add(this, v2->array[i]);
Hisham Muhammad's avatar
Hisham Muhammad committed
221
   v2->items = 0;
222
223
   Vector_delete(v2);
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
224
225
}

226
void Vector_add(Vector* this, void* data_) {
Hisham Muhammad's avatar
Hisham Muhammad committed
227
228
   assert(data_ && ((Object*)data_)->class == this->vectorType);
   Object* data = data_;
229
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
230

231
232
   Vector_set(this, this->items, data);
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
233
234
}

235
inline int Vector_indexOf(Vector* this, void* search_) {
Hisham Muhammad's avatar
Hisham Muhammad committed
236
237
   assert(((Object*)search_)->class == this->vectorType);
   Object* search = search_;
238
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
239
240
241
242
243
244
245
246
247
248
249

   int i;

   for (i = 0; i < this->items; i++) {
      Object* o = (Object*)this->array[i];
      if (o && o->compare(o, search) == 0)
         return i;
   }
   return -1;
}

250
void Vector_foreach(Vector* this, Vector_procedure f) {
Hisham Muhammad's avatar
Hisham Muhammad committed
251
   int i;
252
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
253
254
255

   for (i = 0; i < this->items; i++)
      f(this->array[i]);
256
   assert(Vector_isConsistent(this));
Hisham Muhammad's avatar
Hisham Muhammad committed
257
}