File: PoolSQL.h

package info (click to toggle)
opennebula 3.4.1-3.1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 9,680 kB
  • sloc: cpp: 35,288; ruby: 24,818; sh: 5,212; java: 4,001; xml: 1,163; yacc: 821; sql: 252; lex: 216; ansic: 192; makefile: 91; python: 46
file content (331 lines) | stat: -rw-r--r-- 9,825 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org)             */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#ifndef POOL_SQL_H_
#define POOL_SQL_H_

#include <map>
#include <string>
#include <queue>

#include "SqlDB.h"
#include "PoolObjectSQL.h"
#include "Log.h"
#include "Hook.h"

using namespace std;

/**
 * PoolSQL class. Provides a base class to implement persistent generic pools.
 * The PoolSQL provides a synchronization mechanism (mutex) to operate in
 * multithreaded applications. Any modification or access function to the pool
 * SHOULD block the mutex.
 */
class PoolSQL: public Callbackable, public Hookable
{
public:
    /**
     * Initializes the oid counter. This function sets lastOID to
     * the last used Object identifier by querying the corresponding database
     * table. This function SHOULD be called before any pool related function.
     *   @param _db a pointer to the database
     *   @param _table the name of the table supporting the pool (to set the oid
     *   counter). If null the OID counter is not updated.
     *   @param cache_by_name True if the objects can be retrieved by name
     */
    PoolSQL(SqlDB * _db, const char * _table, bool cache_by_name);

    virtual ~PoolSQL();

    /**
     *  Allocates a new object, writting it in the pool database. No memory is
     *  allocated for the object.
     *   @param objsql an initialized ObjectSQL
     *   @return the oid assigned to the object or -1 in case of failure
     */
    virtual int allocate(
        PoolObjectSQL   *objsql,
        string&          error_str);

    /**
     *  Gets an object from the pool (if needed the object is loaded from the
     *  database).
     *   @param oid the object unique identifier
     *   @param lock locks the object if true
     *
     *   @return a pointer to the object, 0 in case of failure
     */
    PoolObjectSQL * get(int oid, bool lock);

    /**
     * Updates the cache name index. Must be called when the owner of an object
     * is changed
     *
     * @param old_name Object's name before the change
     * @param old_uid Object's owner ID before the change
     * @param new_name Object's name after the change
     * @param new_uid Object's owner ID after the change
     */
    void update_cache_index(string& old_name,
                            int     old_uid,
                            string& new_name,
                            int     new_uid);

    /**
     *  Finds a set objects that satisfies a given condition
     *   @param oids a vector with the oids of the objects.
     *   @param the name of the DB table.
     *   @param where condition in SQL format.
     *
     *   @return 0 on success
     */
    virtual int search(
        vector<int>&    oids,
        const char *    table,
        const string&   where);

    /**
     *  Updates the object's data in the data base. The object mutex SHOULD be
     *  locked.
     *    @param objsql a pointer to the object
     *
     *    @return 0 on success.
     */
    virtual int update(
        PoolObjectSQL * objsql)
    {
        int rc;

        rc = objsql->update(db);

        if ( rc == 0 )
        {
            do_hooks(objsql, Hook::UPDATE);
        }

        return rc;
    };

    /**
     *  Drops the object's data in the data base. The object mutex SHOULD be
     *  locked.
     *    @param objsql a pointer to the object
     *    @param error_msg Error reason, if any
     *    @return 0 on success, -1 DB error
     */
    virtual int drop(PoolObjectSQL * objsql, string& error_msg)
    {
        int rc = objsql->drop(db);

        if ( rc != 0 )
        {
            error_msg = "SQL DB error";
            return -1;
        }

        return 0;
    };

    /**
     *  Removes all the elements from the pool
     */
    void clean();

    /**
     *  Dumps the pool in XML format. A filter can be also added to the
     *  query
     *  @param oss the output stream to dump the pool contents
     *  @param where filter for the objects, defaults to all
     *
     *  @return 0 on success
     */
    virtual int dump(ostringstream& oss, const string& where) = 0;

protected:

    /**
     *  Gets an object from the pool (if needed the object is loaded from the
     *  database).
     *   @param name of the object
     *   @param uid id of owner
     *   @param lock locks the object if true
     *
     *   @return a pointer to the object, 0 in case of failure
     */
    PoolObjectSQL * get(const string& name, int uid, bool lock);

    /**
     *  Pointer to the database.
     */
    SqlDB * db;

    /**
     *  Dumps the pool in XML format. A filter can be also added to the
     *  query
     *  @param oss the output stream to dump the pool contents
     *  @param elem_name Name of the root xml pool name
     *  @param table Pool table name
     *  @param where filter for the objects, defaults to all
     *
     *  @return 0 on success
     */
    int dump(ostringstream& oss, const string& elem_name,
             const char * table, const string& where);

    /* ---------------------------------------------------------------------- */
    /* Interface to access the lastOID assigned by the pool                   */
    /* ---------------------------------------------------------------------- */

    /**
     *  Gets the value of the last identifier assigned by the pool
     *   @return the lastOID of the pool
     */
    int get_lastOID()
    {
        return lastOID;
    };

    /**
     *  Sets the lastOID of the pool and updates the control database
     *    @param _lastOID for the pool
     */
    void set_update_lastOID(int _lastOID)
    {
        lastOID = _lastOID;

        update_lastOID();
    };

private:

    pthread_mutex_t mutex;

    /**
     *  Max size for the pool, to control the memory footprint of the pool. This
     *  number MUST be greater than the max. number of objects that are
     *  accessed simultaneously.
     */
    static const unsigned int MAX_POOL_SIZE;

    /**
     *  Last object ID assigned to an object. It must be initialized by the
     *  target pool.
     */
    int lastOID;

    /**
     *  Tablename for this pool
     */
    string table;

    /**
     *  The pool is implemented with a Map of SQL object pointers, using the
     *  OID as key.
     */
    map<int,PoolObjectSQL *> pool;

    /**
     * Whether or not this pool uses the name_pool index
     */
    bool uses_name_pool;

    /**
     *  This is a name index for the pool map. The key is the name of the object
     *  , that may be combained with the owner id.
     */
    map<string,PoolObjectSQL *> name_pool;

    /**
     *  Factory method, must return an ObjectSQL pointer to an allocated pool
     *  specific object.
     */
    virtual PoolObjectSQL * create() = 0;

    /**
     *  OID queue to implement a FIFO-like replacement policy for the pool
     *  cache.
     */
    queue<int> oid_queue;

    /**
     *  Function to lock the pool
     */
    void lock()
    {
        pthread_mutex_lock(&mutex);
    };

    /**
     *  Function to unlock the pool
     */
    void unlock()
    {
        pthread_mutex_unlock(&mutex);
    };

    /**
     *  FIFO-like replacement policy function. Before removing an object (pop)
     *  from  the cache its lock is checked. The object is removed only if
     *  the associated mutex IS NOT blocked. Otherwise the oid is sent to the
     *  back of the queue.
     */
    void replace();

    /**
     *  Generate an index key for the object
     *    @param name of the object
     *    @param uid owner of the object, only used if needed
     *    
     *    @return the key, a string
     */
    virtual string key(const string& name, int uid)
    {
        ostringstream key;

        key << name << ':' << uid;

        return key.str();
    };

    /**
     *  Inserts the last oid into the pool_control table
     */
    void update_lastOID();

    /* ---------------------------------------------------------------------- */
    /* ---------------------------------------------------------------------- */

    /**
     *  Callback to set the lastOID (PoolSQL::PoolSQL)
     */
    int  init_cb(void *nil, int num, char **values, char **names);

    /**
     *  Callback to store the IDs of pool objects (PoolSQL::search)
     */
    int  search_cb(void *_oids, int num, char **values, char **names);

    /**
     *  Callback function to get output in XML format
     *    @param num the number of columns read from the DB
     *    @param names the column names
     *    @param vaues the column values
     *    @return 0 on success
     */
    int dump_cb(void * _oss, int num, char **values, char **names);
};

#endif /*POOL_SQL_H_*/