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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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)
58
cs_realloc((void **) &iTable, sizeof(CSObject *) * size);
63
void CSHashTable::add(CSObject *item)
65
uint32_t h = item->hashKey();
67
remove(item->getKey());
68
item->setHashLink(iTable[h % iSize]);
69
iTable[h % iSize] = item;
72
CSObject *CSHashTable::find(CSObject *key)
74
uint32_t h = key->hashKey();
77
item = iTable[h % iSize];
79
if (item->hashKey() == h && item->compareKey(key) == 0)
81
item = item->getHashLink();
86
void CSHashTable::remove(CSObject *key)
88
uint32_t h = key->hashKey();
89
CSObject *item, *prev_item;
92
item = iTable[h % iSize];
94
if (item->hashKey() == h && item->compareKey(key) == 0) {
95
/* Remove the object: */
97
prev_item->setHashLink(item->getHashLink());
99
iTable[h % iSize] = item->getHashLink();
104
item = item->getHashLink();
108
void CSHashTable::clear()
110
CSObject *item, *tmp_item;
112
for (uint32_t i=0; i<iSize; i++) {
114
while ((tmp_item = item)) {
115
item = tmp_item->getHashLink();
122
* ---------------------------------------------------------------
126
void CSSortedList::clear()
129
for (uint32_t i=0; i<iInUse; i++)
138
void CSSortedList::add(CSObject *item)
144
if ((old_item = search(item->getKey(), idx))) {
149
if (iInUse == iListSize) {
151
cs_realloc((void **) &iList, (iListSize + SC_SORT_LIST_INC_SIZE) * sizeof(CSObject *));
153
iListSize += SC_SORT_LIST_INC_SIZE;
155
memmove(&iList[idx+1], &iList[idx], (iInUse - idx) * sizeof(CSObject *));
162
CSObject *CSSortedList::find(CSObject *key)
166
return search(key, idx);
169
CSObject *CSSortedList::itemAt(uint32_t idx)
176
CSObject *CSSortedList::takeItemAt(uint32_t idx)
185
memmove(&iList[idx], &iList[idx+1], (iInUse - idx) * sizeof(CSObject *));
190
void CSSortedList::remove(CSObject *key)
195
if ((item = search(key, idx))) {
196
memmove(&iList[idx], &iList[idx+1], (iInUse - idx) * sizeof(CSObject *));
202
CSObject *CSSortedList::search(CSObject *key, uint32_t& idx)
204
register uint32_t count = iInUse;
206
register uint32_t guess;
211
guess = (i + count - 1) >> 1;
212
r = iList[guess]->compareKey(key);
228
* ---------------------------------------------------------------
233
* ---------------------------------------------------------------
237
void CSLinkedList::clear()
243
void CSLinkedList::addFront(CSObject *item)
245
if (iListFront != item) {
247
item->setNextLink(NULL);
248
item->setPrevLink(iListFront);
250
iListFront->setNextLink(item);
257
/* Must do this or I will have one reference too
259
* The input object was given to me referenced,
260
* but I already have the object on my list, and
266
bool CSLinkedList::remove(CSObject *item)
268
bool on_list = false;
270
if (item->getNextLink()) {
271
item->getNextLink()->setPrevLink(item->getPrevLink());
274
if (item->getPrevLink()) {
275
item->getPrevLink()->setNextLink(item->getNextLink());
278
if (iListFront == item) {
279
iListFront = item->getPrevLink();
282
if (iListBack == item) {
283
iListBack = item->getNextLink();
286
item->setNextLink(NULL);
287
item->setPrevLink(NULL);
296
CSObject *CSLinkedList::removeBack()
298
CSObject *item = iListBack;
301
/* Removing dereferences the object! */
302
remove(RETAIN(item));
307
CSObject *CSLinkedList::getBack()
312
CSObject *CSLinkedList::removeFront()
314
CSObject *item = iListFront;
317
/* Removing dereferences the object! */
318
remove(RETAIN(item));
323
CSObject *CSLinkedList::getFront()
329
* ---------------------------------------------------------------
333
void CSVector::free()
343
void CSVector::clear()
362
CSObject *CSVector::take(uint32_t idx)
371
memmove(&iArray[idx], &iArray[idx+1], (iUsage - idx) * sizeof(CSObject *));
375
void CSVector::remove(uint32_t idx)
384
memmove(&iArray[idx], &iArray[idx+1], (iUsage - idx) * sizeof(CSObject *));
388
CSObject *CSVector::get(uint32_t idx)
395
void CSVector::set(uint32_t idx, CSObject *val)
398
if (idx >= iMaxSize) {
400
cs_realloc((void **) &iArray, sizeof(CSObject *) * (idx + iGrowSize - 1));
402
iMaxSize = idx + iGrowSize - 1;
406
memset(&iArray[iUsage], 0, sizeof(CSObject *) * (idx - iUsage));
409
else if (iArray[idx]) {
411
iArray[idx]->release();
418
void CSVector::add(CSObject *obj)
421
if (iUsage == iMaxSize) {
423
cs_realloc((void **) &iArray, sizeof(CSObject *) * (iMaxSize + iGrowSize));
425
iMaxSize += iGrowSize;
427
iArray[iUsage] = obj;
433
* ---------------------------------------------------------------
437
void CSSparseArray::free()
447
void CSSparseArray::clear()
455
if (iArray[i].sa_object) {
458
obj = iArray[i].sa_object;
459
iArray[i].sa_object = NULL;
466
CSObject *CSSparseArray::take(uint32_t idx)
471
if (!(obj = search(idx, pos)))
474
memmove(&iArray[pos], &iArray[pos+1], (iUsage - pos) * sizeof(CSSpareArrayItemRec));
478
void CSSparseArray::remove(uint32_t idx)
483
if (!(obj = search(idx, pos)))
486
memmove(&iArray[pos], &iArray[pos+1], (iUsage - pos) * sizeof(CSSpareArrayItemRec));
490
CSObject *CSSparseArray::itemAt(uint32_t idx)
494
return iArray[idx].sa_object;
497
CSObject *CSSparseArray::get(uint32_t idx)
501
return search(idx, pos);
504
uint32_t CSSparseArray::getIndex(uint32_t idx)
512
void CSSparseArray::set(uint32_t idx, CSObject *val)
520
if ((obj = search(idx, pos)))
523
if (iUsage == iMaxSize) {
524
cs_realloc((void **) &iArray, (iMaxSize + iGrowSize) * sizeof(CSSpareArrayItemRec));
525
iMaxSize += iGrowSize;
527
memmove(&iArray[pos+1], &iArray[pos], (iUsage - pos) * sizeof(CSSpareArrayItemRec));
529
iArray[pos].sa_index = idx;
532
iArray[pos].sa_object = val;
536
void CSSparseArray::removeFirst()
539
remove(iArray[0].sa_index);
542
CSObject *CSSparseArray::first()
546
return iArray[0].sa_object;
549
CSObject *CSSparseArray::last()
553
return iArray[iUsage-1].sa_object;
556
CSObject *CSSparseArray::search(uint32_t idx, uint32_t& pos)
558
register uint32_t count = iUsage;
560
register uint32_t guess;
564
guess = (i + count - 1) >> 1;
565
if (idx == iArray[guess].sa_index) {
567
return iArray[guess].sa_object;
569
if (idx < iArray[guess].sa_index)
580
* ---------------------------------------------------------------
584
void CSOrderedList::clear()
587
for (uint32_t i=0; i<iInUse; i++) {
589
iList[i].li_key->release();
590
if (iList[i].li_item)
591
iList[i].li_item->release();
600
CSObject *CSOrderedList::itemAt(uint32_t idx)
604
return iList[idx].li_item;
608
void CSOrderedList::add(CSOrderKey *key, CSObject *item)
610
CSOrderedListItemPtr old_item;
614
if ((old_item = search(key, &idx))) {
615
iList[idx].li_key = key;
616
iList[idx].li_item = item;
617
if (old_item->li_key)
618
old_item->li_key->release();
619
if (old_item->li_item)
620
old_item->li_item->release();
623
if (iInUse == iListSize) {
626
cs_realloc((void **) &iList, (iListSize + SC_SORT_LIST_INC_SIZE) * sizeof(CSOrderedListItemRec));
629
iListSize += SC_SORT_LIST_INC_SIZE;
631
memmove(&iList[idx+1], &iList[idx], (iInUse - idx) * sizeof(CSOrderedListItemRec));
633
iList[idx].li_key = key;
634
iList[idx].li_item = item;
639
CSObject *CSOrderedList::find(CSOrderKey *key)
642
CSOrderedListItemPtr ptr;
644
if ((ptr = search(key, &idx)))
649
void CSOrderedList::remove(CSOrderKey *key)
651
CSOrderedListItemPtr item;
654
if ((item = search(key, &idx))) {
655
CSOrderedListItemRec ir;
657
memcpy(&ir, item, sizeof(CSOrderedListItemRec));
658
memmove(&iList[idx], &iList[idx+1], (iInUse - idx) * sizeof(CSOrderedListItemRec));
661
ir.li_key->release();
663
ir.li_item->release();
667
CSOrderedListItemPtr CSOrderedList::search(CSOrderKey *key, uint32_t *idx)
669
register uint32_t count = iInUse;
671
register uint32_t guess;
676
guess = (i + count - 1) >> 1;
677
r = iList[guess].li_key->compareKey(key);
680
return &iList[guess];