1
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
3
* PrimeBase Media Stream for MySQL
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
* Original author: Paul McCullagh (H&G2JCtL)
20
* Continued development: Barry Leslie
25
* Basic storage structures.
36
#include "CSStorage.h"
40
* ---------------------------------------------------------------
44
CSHashTable::~CSHashTable()
55
void CSHashTable::setSize(uint32_t size)
65
cs_realloc((void **) &iTable, sizeof(CSObject *) * size);
66
memset(iTable, 0, sizeof(CSObject *) * size);
72
void CSHashTable::add(CSObject *item)
74
uint32_t h = item->hashKey();
76
remove(item->getKey());
77
item->setHashLink(iTable[h % iSize]);
78
iTable[h % iSize] = item;
81
CSObject *CSHashTable::find(CSObject *key)
83
uint32_t h = key->hashKey();
86
item = iTable[h % iSize];
88
if (item->hashKey() == h && item->compareKey(key) == 0)
90
item = item->getHashLink();
95
bool CSHashTable::remove(CSObject *key)
97
uint32_t h = key->hashKey();
98
CSObject *item, *prev_item;
101
item = iTable[h % iSize];
103
if (item->hashKey() == h && item->compareKey(key) == 0) {
104
/* Remove the object: */
106
prev_item->setHashLink(item->getHashLink());
108
iTable[h % iSize] = item->getHashLink();
113
item = item->getHashLink();
118
void CSHashTable::clear()
120
CSObject *item, *tmp_item;
122
for (uint32_t i=0; i<iSize; i++) {
124
while ((tmp_item = item)) {
125
item = tmp_item->getHashLink();
132
* ---------------------------------------------------------------
136
void CSSortedList::clear()
139
for (uint32_t i=0; i<iInUse; i++)
148
void CSSortedList::add(CSObject *item)
154
if ((old_item = search(item->getKey(), idx))) {
159
if (iInUse == iListSize) {
161
cs_realloc((void **) &iList, (iListSize + SC_SORT_LIST_INC_SIZE) * sizeof(CSObject *));
163
iListSize += SC_SORT_LIST_INC_SIZE;
165
memmove(&iList[idx+1], &iList[idx], (iInUse - idx) * sizeof(CSObject *));
172
CSObject *CSSortedList::find(CSObject *key)
176
return search(key, idx);
179
CSObject *CSSortedList::itemAt(uint32_t idx)
186
CSObject *CSSortedList::takeItemAt(uint32_t idx)
196
memmove(&iList[idx], &iList[idx+1], (iInUse - idx) * sizeof(CSObject *));
200
void CSSortedList::remove(CSObject *key)
205
if ((item = search(key, idx))) {
207
memmove(&iList[idx], &iList[idx+1], (iInUse - idx) * sizeof(CSObject *));
212
CSObject *CSSortedList::search(CSObject *key, uint32_t& idx)
214
register uint32_t count = iInUse;
216
register uint32_t guess;
221
guess = (i + count - 1) >> 1;
222
r = iList[guess]->compareKey(key);
238
* ---------------------------------------------------------------
243
* ---------------------------------------------------------------
247
void CSLinkedList::clear()
253
void CSLinkedList::addFront(CSObject *item)
255
if (iListFront != item) {
257
item->setNextLink(NULL);
258
item->setPrevLink(iListFront);
260
iListFront->setNextLink(item);
267
/* Must do this or I will have one reference too
269
* The input object was given to me referenced,
270
* but I already have the object on my list, and
276
void CSLinkedList::addBack(CSObject *item)
278
if (iListBack != item) {
280
item->setNextLink(iListBack);
281
item->setPrevLink(NULL);
284
iListBack->setPrevLink(item);
291
/* Must do this or I will have one reference too
293
* The input object was given to me referenced,
294
* but I already have the object on my list, and
300
bool CSLinkedList::remove(CSObject *item)
302
bool on_list = false;
304
if (item->getNextLink()) {
305
item->getNextLink()->setPrevLink(item->getPrevLink());
308
if (item->getPrevLink()) {
309
item->getPrevLink()->setNextLink(item->getNextLink());
312
if (iListFront == item) {
313
iListFront = item->getPrevLink();
316
if (iListBack == item) {
317
iListBack = item->getNextLink();
320
item->setNextLink(NULL);
321
item->setPrevLink(NULL);
330
CSObject *CSLinkedList::removeBack()
332
CSObject *item = iListBack;
335
/* Removing dereferences the object! */
336
remove(RETAIN(item));
341
CSObject *CSLinkedList::getBack()
346
CSObject *CSLinkedList::removeFront()
348
CSObject *item = iListFront;
351
/* Removing dereferences the object! */
352
remove(RETAIN(item));
357
CSObject *CSLinkedList::getFront()
363
* ---------------------------------------------------------------
367
void CSVector::free()
377
void CSVector::clear()
396
CSObject *CSVector::take(uint32_t idx)
405
memmove(&iArray[idx], &iArray[idx+1], (iUsage - idx) * sizeof(CSObject *));
409
void CSVector::remove(uint32_t idx)
418
memmove(&iArray[idx], &iArray[idx+1], (iUsage - idx) * sizeof(CSObject *));
422
CSObject *CSVector::get(uint32_t idx)
429
void CSVector::set(uint32_t idx, CSObject *val)
432
if (idx >= iMaxSize) {
434
cs_realloc((void **) &iArray, sizeof(CSObject *) * (idx + iGrowSize - 1));
436
iMaxSize = idx + iGrowSize - 1;
440
memset(&iArray[iUsage], 0, sizeof(CSObject *) * (idx - iUsage));
443
else if (iArray[idx]) {
445
iArray[idx]->release();
452
void CSVector::add(CSObject *obj)
455
if (iUsage == iMaxSize) {
457
cs_realloc((void **) &iArray, sizeof(CSObject *) * (iMaxSize + iGrowSize));
459
iMaxSize += iGrowSize;
461
iArray[iUsage] = obj;
467
* ---------------------------------------------------------------
471
void CSSparseArray::free()
481
void CSSparseArray::clear()
489
if (iArray[i].sa_object) {
492
obj = iArray[i].sa_object;
493
iArray[i].sa_object = NULL;
500
CSObject *CSSparseArray::take(uint32_t idx)
505
if (!(obj = search(idx, pos)))
508
memmove(&iArray[pos], &iArray[pos+1], (iUsage - pos) * sizeof(CSSpareArrayItemRec));
512
void CSSparseArray::remove(uint32_t idx)
517
if (!(obj = search(idx, pos)))
520
memmove(&iArray[pos], &iArray[pos+1], (iUsage - pos) * sizeof(CSSpareArrayItemRec));
524
CSObject *CSSparseArray::itemAt(uint32_t idx)
528
return iArray[idx].sa_object;
531
CSObject *CSSparseArray::get(uint32_t idx)
535
return search(idx, pos);
538
uint32_t CSSparseArray::getIndex(uint32_t idx)
542
// If search fails then pos will be > iUsage
547
void CSSparseArray::set(uint32_t idx, CSObject *val)
555
if ((obj = search(idx, pos)))
558
if (iUsage == iMaxSize) {
559
cs_realloc((void **) &iArray, (iMaxSize + iGrowSize) * sizeof(CSSpareArrayItemRec));
560
iMaxSize += iGrowSize;
562
memmove(&iArray[pos+1], &iArray[pos], (iUsage - pos) * sizeof(CSSpareArrayItemRec));
564
iArray[pos].sa_index = idx;
567
iArray[pos].sa_object = val;
571
void CSSparseArray::removeFirst()
574
remove(iArray[0].sa_index);
577
CSObject *CSSparseArray::first()
581
return iArray[0].sa_object;
584
CSObject *CSSparseArray::last()
588
return iArray[iUsage-1].sa_object;
591
CSObject *CSSparseArray::search(uint32_t idx, uint32_t& pos)
593
register uint32_t count = iUsage;
595
register uint32_t guess;
599
guess = (i + count - 1) >> 1;
600
if (idx == iArray[guess].sa_index) {
602
return iArray[guess].sa_object;
604
if (idx < iArray[guess].sa_index)
615
* ---------------------------------------------------------------
619
void CSOrderedList::clear()
622
for (uint32_t i=0; i<iInUse; i++) {
624
iList[i].li_key->release();
625
if (iList[i].li_item)
626
iList[i].li_item->release();
635
CSObject *CSOrderedList::itemAt(uint32_t idx)
639
return iList[idx].li_item;
643
void CSOrderedList::add(CSOrderKey *key, CSObject *item)
645
CSOrderedListItemPtr old_item;
649
if ((old_item = search(key, &idx))) {
650
iList[idx].li_key = key;
651
iList[idx].li_item = item;
652
if (old_item->li_key)
653
old_item->li_key->release();
654
if (old_item->li_item)
655
old_item->li_item->release();
658
if (iInUse == iListSize) {
661
cs_realloc((void **) &iList, (iListSize + SC_SORT_LIST_INC_SIZE) * sizeof(CSOrderedListItemRec));
664
iListSize += SC_SORT_LIST_INC_SIZE;
666
memmove(&iList[idx+1], &iList[idx], (iInUse - idx) * sizeof(CSOrderedListItemRec));
668
iList[idx].li_key = key;
669
iList[idx].li_item = item;
674
CSObject *CSOrderedList::find(CSOrderKey *key)
677
CSOrderedListItemPtr ptr;
679
if ((ptr = search(key, &idx)))
684
void CSOrderedList::remove(CSOrderKey *key)
686
CSOrderedListItemPtr item;
689
if ((item = search(key, &idx))) {
690
CSOrderedListItemRec ir;
692
memcpy(&ir, item, sizeof(CSOrderedListItemRec));
694
memmove(&iList[idx], &iList[idx+1], (iInUse - idx) * sizeof(CSOrderedListItemRec));
696
ir.li_key->release();
698
ir.li_item->release();
702
CSOrderedListItemPtr CSOrderedList::search(CSOrderKey *key, uint32_t *idx)
704
register uint32_t count = iInUse;
706
register uint32_t guess;
711
guess = (i + count - 1) >> 1;
712
r = iList[guess].li_key->compareKey(key);
715
return &iList[guess];