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(u_int size)
58
cs_realloc((void **) &iTable, sizeof(CSObject *) * size);
63
void CSHashTable::add(CSObject *item)
65
u_int 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
u_int 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
u_int 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 (u_int i=0; i<iSize; i++) {
114
while ((tmp_item = item)) {
115
item = tmp_item->getHashLink();
122
* ---------------------------------------------------------------
126
void CSSortedList::clear()
129
for (u_int 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(u_int idx)
176
CSObject *CSSortedList::takeItemAt(u_int 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, u_int& idx)
204
register u_int count = iInUse;
206
register u_int 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(u_int idx)
371
memmove(&iArray[idx], &iArray[idx+1], (iUsage - idx) * sizeof(CSObject *));
375
void CSVector::remove(u_int idx)
384
memmove(&iArray[idx], &iArray[idx+1], (iUsage - idx) * sizeof(CSObject *));
388
CSObject *CSVector::get(u_int idx)
395
void CSVector::set(u_int 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));
430
iMaxSize += iGrowSize;
432
iArray[iUsage] = obj;
438
* ---------------------------------------------------------------
442
void CSSparseArray::free()
452
void CSSparseArray::clear()
460
if (iArray[i].sa_object) {
463
obj = iArray[i].sa_object;
464
iArray[i].sa_object = NULL;
471
CSObject *CSSparseArray::take(u_int idx)
476
if (!(obj = search(idx, pos)))
479
memmove(&iArray[pos], &iArray[pos+1], (iUsage - pos) * sizeof(CSSpareArrayItemRec));
483
void CSSparseArray::remove(u_int idx)
488
if (!(obj = search(idx, pos)))
491
memmove(&iArray[pos], &iArray[pos+1], (iUsage - pos) * sizeof(CSSpareArrayItemRec));
495
CSObject *CSSparseArray::itemAt(u_int idx)
499
return iArray[idx].sa_object;
502
CSObject *CSSparseArray::get(u_int idx)
506
return search(idx, pos);
509
u_int CSSparseArray::getIndex(u_int idx)
517
void CSSparseArray::set(u_int idx, CSObject *val)
525
if ((obj = search(idx, pos)))
528
if (iUsage == iMaxSize) {
529
cs_realloc((void **) &iArray, (iMaxSize + iGrowSize) * sizeof(CSSpareArrayItemRec));
530
iMaxSize += iGrowSize;
532
memmove(&iArray[pos+1], &iArray[pos], (iUsage - pos) * sizeof(CSSpareArrayItemRec));
534
iArray[pos].sa_index = idx;
537
iArray[pos].sa_object = val;
541
void CSSparseArray::removeFirst()
544
remove(iArray[0].sa_index);
547
CSObject *CSSparseArray::first()
551
return iArray[0].sa_object;
554
CSObject *CSSparseArray::last()
558
return iArray[iUsage-1].sa_object;
561
CSObject *CSSparseArray::search(u_int idx, u_int& pos)
563
register u_int count = iUsage;
565
register u_int guess;
569
guess = (i + count - 1) >> 1;
570
if (idx == iArray[guess].sa_index) {
572
return iArray[guess].sa_object;
574
if (idx < iArray[guess].sa_index)
585
* ---------------------------------------------------------------
589
void CSOrderedList::clear()
592
for (u_int i=0; i<iInUse; i++) {
594
iList[i].li_key->release();
595
if (iList[i].li_item)
596
iList[i].li_item->release();
605
CSObject *CSOrderedList::itemAt(u_int idx)
609
return iList[idx].li_item;
613
void CSOrderedList::add(CSOrderKey *key, CSObject *item)
615
CSOrderedListItemPtr old_item;
619
if ((old_item = search(key, &idx))) {
620
iList[idx].li_key = key;
621
iList[idx].li_item = item;
622
if (old_item->li_key)
623
old_item->li_key->release();
624
if (old_item->li_item)
625
old_item->li_item->release();
628
if (iInUse == iListSize) {
631
cs_realloc((void **) &iList, (iListSize + SC_SORT_LIST_INC_SIZE) * sizeof(CSOrderedListItemRec));
634
iListSize += SC_SORT_LIST_INC_SIZE;
636
memmove(&iList[idx+1], &iList[idx], (iInUse - idx) * sizeof(CSOrderedListItemRec));
638
iList[idx].li_key = key;
639
iList[idx].li_item = item;
644
CSObject *CSOrderedList::find(CSOrderKey *key)
647
CSOrderedListItemPtr ptr;
649
if ((ptr = search(key, &idx)))
654
void CSOrderedList::remove(CSOrderKey *key)
656
CSOrderedListItemPtr item;
659
if ((item = search(key, &idx))) {
660
CSOrderedListItemRec ir;
662
memcpy(&ir, item, sizeof(CSOrderedListItemRec));
663
memmove(&iList[idx], &iList[idx+1], (iInUse - idx) * sizeof(CSOrderedListItemRec));
666
ir.li_key->release();
668
ir.li_item->release();
672
CSOrderedListItemPtr CSOrderedList::search(CSOrderKey *key, u_int *idx)
674
register u_int count = iInUse;
676
register u_int guess;
681
guess = (i + count - 1) >> 1;
682
r = iList[guess].li_key->compareKey(key);
685
return &iList[guess];