File: gb_data.h

package info (click to toggle)
arb 6.0.6-8
  • links: PTS, VCS
  • area: non-free
  • in suites: sid, trixie
  • size: 66,204 kB
  • sloc: ansic: 394,911; cpp: 250,290; makefile: 19,644; sh: 15,879; perl: 10,473; fortran: 6,019; ruby: 683; xml: 503; python: 53; awk: 32
file content (326 lines) | stat: -rw-r--r-- 11,090 bytes parent folder | download | duplicates (6)
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
// =============================================================== //
//                                                                 //
//   File      : gb_data.h                                         //
//   Purpose   : GBDATA/GBCONTAINER                                //
//                                                                 //
//   Institute of Microbiology (Technical University Munich)       //
//   http://www.arb-home.de/                                       //
//                                                                 //
// =============================================================== //

#ifndef GB_DATA_H
#define GB_DATA_H

#ifndef GB_LOCAL_H
#include "gb_local.h"
#endif
#ifndef GB_MEMORY_H
#include "gb_memory.h"
#endif

struct gb_callback_list;

// --------------------------------------------------------------------------------

#define SIZOFINTERN 10

struct gb_extern_data {
    GB_REL_STRING rel_data;
    long          memsize;
    long          size;

    char *get_data() { return GB_RESOLVE(char*, this, rel_data); }
    void set_data(char *data) { GB_SETREL(this, rel_data, data); }
};

struct GB_INTern_strings {
    char          data[SIZOFINTERN];
    unsigned char memsize;
    unsigned char size;
};

struct GB_INTern {
    char data[SIZOFINTERN];
};

union gb_data_base_type_union {
    int32_t            i;
    GBDATA            *ptr;
    GB_INTern_strings  istr;
    GB_INTern          in;
    gb_extern_data     ex;
};

// --------------------------------------------------------------------------------

struct gb_db_extended {
    long                 creation_date;
    long                 update_date;
    gb_callback_list    *callback;
    gb_transaction_save *old;
};

// --------------------------------------------------------------------------------

struct gb_flag_types {                                                  // public flags
    unsigned int type : 4;
    unsigned int security_delete : 3;
    unsigned int security_write : 3;
    unsigned int security_read : 3;
    unsigned int compressed_data : 1;
    unsigned int unused : 1;                                            // last bit saved!
    unsigned int user_flags : 8;
    unsigned int temporary : 1;                                         // ==1 -> don't save entry
    unsigned int saved_flags : 8;
};

struct gb_flag_types2 { // private flags (DB server and each client have their own copy!), abortable
    // uncritical section, undoable
    unsigned int last_updated : 8;
    unsigned int user_bits : 7;                                         // user flags (see GB_USERFLAG_...)
    // critic section, do not update any below
    unsigned int folded_container : 1;
    unsigned int update_in_server : 1;                                  // already informed
    unsigned int extern_data : 1;                                       // data ref. by pntr
    unsigned int header_changed : 1;                                    // used by container
    unsigned int gbm_index : 8;                                         // memory section
    unsigned int should_be_indexed : 1;                                 // this should be indexed
    unsigned int is_indexed : 1;                                        // this db. field is indexed
};

struct gb_flag_types3 {                                                 // user and project flags (public); not abortable !!!
    unsigned int project : 8;
    unsigned int unused : 24;
};

// --------------------------------------------------------------------------------

struct gb_data_list {
    GB_REL_HLS rel_header;
    int        headermemsize; // array size (allocated entries)
    int        size;          // number of valid (non-deleted) items - not valid in transaction mode
    int        nheader;       // index of next new entry
};

inline gb_header_list *GB_DATA_LIST_HEADER(gb_data_list& dl) {
    return GB_RESOLVE(gb_header_list *, (&(dl)), rel_header);
}
inline void SET_GB_DATA_LIST_HEADER(gb_data_list& dl, gb_header_list *head) {
    GB_SETREL(&dl, rel_header, head);
}

// --------------------------------------------------------------------------------

#if defined(DEBUG)
#define ASSERT_STRICT_GBDATA_TYPES // just for refactoring/debugging (slow)
#endif

#if defined(ASSERT_STRICT_GBDATA_TYPES)
#define gb_strict_assert(cond) gb_assert(cond)
#else
#define gb_strict_assert(cond)
#endif

struct GBENTRY;
struct GBCONTAINER;

#define GB_GBM_INDEX(gbd) ((gbd)->flags2.gbm_index)

struct GBDATA {
    long              server_id;
    GB_REL_CONTAINER  rel_father;
    gb_db_extended   *ext;
    long              index;
    gb_flag_types     flags;
    gb_flag_types2    flags2;

    // ----------------------------------------

    GB_TYPES type() const {
        gb_assert(this);
        return GB_TYPES(flags.type);
    }

    bool is_a_string() const { return type() == GB_STRING || type() == GB_LINK; }
    bool is_indexable() const { return is_a_string(); }

    bool is_container() const { return type() == GB_DB; }
    bool is_entry() const { return !is_container(); }

    GBENTRY *as_entry() const {
        gb_strict_assert(!this || is_entry());
        return (GBENTRY*)this;
    }
    GBCONTAINER *as_container() const {
        gb_strict_assert(!this || is_container());
        return (GBCONTAINER*)this;
    }

    // meant to be used in client interface (i.e. on any GBDATA* passed from outside)
    GBENTRY *expect_entry() const {
        if (!is_entry()) GBK_terminate("expected a DB entry, got a container");
        return as_entry();
    }
    GBCONTAINER *expect_container() const {
        if (!is_container()) GBK_terminate("expected a DB container, got an entry");
        return as_container();
    }

    inline GBCONTAINER *get_father();

    void create_extended() {
        if (!ext) {
            ext = (gb_db_extended *)gbm_get_mem(sizeof(gb_db_extended), GB_GBM_INDEX(this));
        }
    }
    void destroy_extended() {
        if (ext) {
            gbm_free_mem(ext, sizeof(gb_db_extended), GB_GBM_INDEX(this));
            ext = NULL;
        }
    }

    void touch_creation(long cdate)           { ext->creation_date = cdate; }
    void touch_update(long udate)             { ext->update_date   = udate; }
    void touch_creation_and_update(long date) { ext->creation_date = ext->update_date = date; }

    long creation_date() const { return ext ? ext->creation_date : 0; }
    long update_date()   const { return ext ? ext->update_date   : 0; }

    gb_callback_list *get_callbacks() const { return ext ? ext->callback : NULL; }
    gb_transaction_save *get_oldData() const { return ext ? ext->old : 0; }
};

class GBENTRY : public GBDATA {
    // calls that make no sense:
    bool is_entry() const;
    GBENTRY *as_entry() const;
public:
    gb_data_base_type_union info;

    int cache_index;

    void mark_as_intern() { flags2.extern_data = 0; }
    void mark_as_extern() { flags2.extern_data = 1; }

    bool stored_external() const { return flags2.extern_data; }
    bool stored_internal() const { return !stored_external(); }

    size_t size()    const { return stored_external() ? info.ex.size    : info.istr.size; }
    size_t memsize() const { return stored_external() ? info.ex.memsize : info.istr.memsize; }

    inline size_t uncompressed_size() const;

    char *data() { return stored_external() ? info.ex.get_data() : &(info.istr.data[0]); }

    inline char *alloc_data(long Size, long Memsize);
    inline void insert_data(const char *Data, long Size, long Memsize);
    void free_data() {
        index_check_out();
        if (stored_external()) {
            char *exdata = info.ex.get_data();
            if (exdata) {
                gbm_free_mem(exdata, (size_t)(info.ex.memsize), GB_GBM_INDEX(this));
                info.ex.set_data(0);
            }
        }
    }

    void index_check_in();
    void index_re_check_in() { if (flags2.should_be_indexed) index_check_in(); }

    void index_check_out();
};

class GBCONTAINER : public GBDATA {
    // calls that make no sense:
    bool is_container() const;
    GBCONTAINER *as_container() const;
public:
    gb_flag_types3 flags3;
    gb_data_list   d;

    long index_of_touched_one_son;  /* index of modified son
                                     * in case of a single mod. son
                                     * -1 more than one (or one with ind = 0)
                                     *  0    no son
                                     * >0   index */
    long header_update_date;

    GB_MAIN_IDX main_idx;
    GB_REL_IFS  rel_ifs;

    void set_touched_idx(int idx) {
        if (!index_of_touched_one_son || index_of_touched_one_son == idx+1) {
            index_of_touched_one_son = idx+1;
        }
        else {
            index_of_touched_one_son = -1;
        }
    }
};

// ----------------------
//      parent access

inline GBCONTAINER* GB_FATHER(GBDATA *gbd)  { return GB_RESOLVE(GBCONTAINER*, gbd, rel_father); }
inline GBCONTAINER* GB_GRANDPA(GBDATA *gbd) { return GB_FATHER(GB_FATHER(gbd)); }

inline void SET_GB_FATHER(GBDATA *gbd, GBCONTAINER *father) { GB_SETREL(gbd, rel_father, father); }

GBCONTAINER *GBDATA::get_father() {
    // like GB_FATHER, but returns NULL for root_container
    GBCONTAINER *father = GB_FATHER(this);
    if (father && !GB_FATHER(father)) return NULL;
    return father;
}


// -----------------------
//      GB_MAIN access

extern GB_MAIN_TYPE *gb_main_array[];

inline GB_MAIN_TYPE *GBCONTAINER_MAIN(GBCONTAINER *gbc) { return gb_main_array[gbc->main_idx]; }

inline GB_MAIN_TYPE *GB_MAIN(GBDATA *gbd)               { return GBCONTAINER_MAIN(GB_FATHER(gbd)); }
inline GB_MAIN_TYPE *GB_MAIN(GBCONTAINER *gbc)          { return GBCONTAINER_MAIN(gbc); }

inline GB_MAIN_TYPE *GB_MAIN_NO_FATHER(GBDATA *gbd) {
    return gbd->is_container() ? GBCONTAINER_MAIN(gbd->as_container()) : GB_MAIN(gbd->as_entry());
}

// -----------------------
//      security flags

#define GB_GET_SECURITY_READ(gb)   ((gb)->flags.security_read)
#define GB_GET_SECURITY_WRITE(gb)  ((gb)->flags.security_write)
#define GB_GET_SECURITY_DELETE(gb) ((gb)->flags.security_delete)

#define GB_PUT_SECURITY_READ(gb, i)  ((gb)->flags.security_read   = (i))
#define GB_PUT_SECURITY_WRITE(gb, i) ((gb)->flags.security_write  = (i))
#define GB_PUT_SECURITY_DELETE(gb, i) ((gb)->flags.security_delete = (i))

// ---------------------------------------------------------
//      strictly-aliased forwarders for some functions:

inline GB_ERROR gb_commit_transaction_local_rek(GBCONTAINER*& gbc, long mode, int *pson_created) {
    return gb_commit_transaction_local_rek(StrictlyAliased_BasePtrRef<GBCONTAINER,GBDATA>(gbc).forward(), mode, pson_created);
}

inline void gb_abort_transaction_local_rek(GBCONTAINER*& gbc) {
    gb_abort_transaction_local_rek(StrictlyAliased_BasePtrRef<GBCONTAINER,GBDATA>(gbc).forward());
}

// --------------------------------------------------------------------------------

#ifndef GB_STORAGE_H
#include "gb_storage.h"
#endif

#else
#error gb_data.h included twice
#endif // GB_DATA_H