source: trunk/src/objects/RpLibStorage.cc

Last change on this file was 5673, checked in by ldelgass, 9 years ago

Fix line endings, set eol-style to native on all C/C++ sources.

  • Property svn:eol-style set to native
File size: 5.3 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  Rappture Library Storage Source
4 *
5 * ======================================================================
6 *  AUTHOR:  Derrick S. Kearney, Purdue University
7 *  Copyright (c) 2004-2012  HUBzero Foundation, LLC
8 *
9 *  See the file "license.terms" for information on usage and
10 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11 * ======================================================================
12 */
13
14#include "RpLibStorage.h"
15#include "RpHashHelper.h"
16
17#include <stdlib.h>
18
19using namespace Rappture;
20
21#define RP_LIBSTORE_FIND    0
22#define RP_LIBSTORE_REMOVE  1
23
24LibraryStorage::LibraryStorage ()
25{
26    _objList = NULL;
27    _objNameHash = NULL;
28
29    __libStoreInit();
30}
31
32LibraryStorage::~LibraryStorage ()
33{
34    __libStoreFree();
35
36    _objList = NULL;
37    _objNameHash = NULL;
38}
39
40void
41LibraryStorage::__libStoreInit()
42{
43    _status.addContext("Rappture::LibraryStorage::__libStoreInit");
44
45    _objList = Rp_ChainCreate();
46    if (_objList == NULL) {
47        _status.addError("Error while allocating space for list");
48    }
49
50    _objNameHash = (Rp_HashTable*) malloc(sizeof(Rp_HashTable));
51    if (_objNameHash == NULL) {
52        _status.addError("Error while allocating space for hash table");
53    } else {
54        Rp_InitHashTable(_objNameHash,RP_STRING_KEYS);
55    }
56
57    return;
58}
59
60void
61LibraryStorage::__libStoreFree()
62{
63    _status.addContext("Rappture::LibraryStorage::__libStoreFree");
64
65    if (_objList != NULL) {
66        Rp_ChainLink *l = NULL;
67        Rappture::Object *objVal = NULL;
68        l = Rp_ChainFirstLink(_objList);
69        while(l) {
70            objVal = (Rappture::Object *) Rp_ChainGetValue(l);
71            delete objVal;
72            objVal = NULL;;
73            l = Rp_ChainNextLink(l);
74        }
75        Rp_ChainDestroy(_objList);
76        _objList = NULL;
77    }
78
79    if (_objNameHash != NULL) {
80        // we dont need to delete the hash table entries because
81        // they point into the chain and the chain has already
82        // deleted the objects.
83
84        Rp_DeleteHashTable(_objNameHash);
85        free(_objNameHash);
86        _objNameHash = NULL;
87    }
88    return;
89}
90
91/*
92Outcome &
93LibraryStorage::backup ()
94{
95    _status.addContext("Rappture::LibraryStorage::backup");
96
97    return _status;
98}
99
100Outcome &
101LibraryStorage::restore ()
102{
103    _status.addContext("Rappture::LibraryStorage::restore");
104
105    return _status;
106}
107*/
108
109Outcome &
110LibraryStorage::store (const char *key, Rappture::Object *o)
111{
112    _status.addContext("Rappture::LibraryStorage::store");
113
114    if (key == NULL) {
115        return _status;
116    }
117
118    if (o == NULL) {
119        return _status;
120    }
121
122    Rp_ChainLink *l = Rp_ChainAppend(_objList, (ClientData)o);
123    if (l == NULL) {
124        _status.addError("Error appending object to list");
125        return _status;
126    }
127
128    Rp_HashAddNode(_objNameHash, key, (ClientData)l);
129
130    return _status;
131}
132
133Outcome &
134LibraryStorage::link (const char *oldkey, const char *newkey)
135{
136    _status.addContext("Rappture::LibraryStorage::link");
137
138    if (oldkey == NULL) {
139        return _status;
140    }
141
142    if (newkey == NULL) {
143        return _status;
144    }
145
146    Rp_HashEntry *hEntry = Rp_FindHashEntry(_objNameHash,oldkey);
147    if (hEntry != NULL) {
148        Rp_ChainLink *l = (Rp_ChainLink *) Rp_GetHashValue(hEntry);
149        if (l != NULL) {
150            Rp_HashAddNode(_objNameHash, newkey, (ClientData)l);
151        }
152    }
153
154    return _status;
155}
156
157Rappture::Object *
158LibraryStorage::find (const char *key)
159{
160    _status.addContext("Rappture::LibraryStorage::find");
161    return __find(key,RP_LIBSTORE_FIND);
162}
163
164Rappture::Object *
165LibraryStorage::remove (const char *key)
166{
167    _status.addContext("Rappture::LibraryStorage::remove");
168    return __find(key,RP_LIBSTORE_REMOVE);
169}
170
171Rappture::Object *
172LibraryStorage::__find(const char *key, size_t flags)
173{
174    _status.addContext("Rappture::LibraryStorage::__find");
175
176    if (key == NULL) {
177        return NULL;
178    }
179
180    Rappture::Object *o = NULL;
181
182    Rp_HashEntry *hEntry = Rp_FindHashEntry(_objNameHash,key);
183    if (hEntry != NULL) {
184        Rp_ChainLink *l = (Rp_ChainLink *) Rp_GetHashValue(hEntry);
185        if (l != NULL) {
186            // chain link exists, try to return its data
187            o = (Rappture::Object *) Rp_ChainGetValue(l);
188            if (o == NULL) {
189                // invalid data in the chain, set remove flag
190                flags |= RP_LIBSTORE_REMOVE;
191            }
192
193            if (RP_LIBSTORE_REMOVE & flags) {
194                // remove flag set
195                // remove it from the chain and hash
196                Rp_ChainDeleteLink(_objList,l);
197                Rp_DeleteHashEntry(_objNameHash,hEntry);
198            }
199        } else {
200            // chain link does not exist, remove hash entry
201            Rp_DeleteHashEntry(_objNameHash,hEntry);
202        }
203    }
204
205    return o;
206}
207
208Outcome &
209LibraryStorage::outcome() const
210{
211    _status.addContext("Rappture::LibraryStorage::outcome");
212    return _status;
213}
214
215const Rp_Chain *
216LibraryStorage::contains() const
217{
218    _status.addContext("Rappture::LibraryStorage::contains");
219    //FIXME: run through hash table and remove invalid entries
220    //       and holes from list before sending it to user
221    return _objList;
222}
223
224Outcome &
225LibraryStorage::clear ()
226{
227    _status.addContext("Rappture::LibraryStorage::clear");
228    __libStoreFree();
229    __libStoreInit();
230    return _status;
231}
Note: See TracBrowser for help on using the repository browser.