1 | // =============================================================== // |
---|
2 | // // |
---|
3 | // File : gb_main.h // |
---|
4 | // Purpose : GB_MAIN_TYPE // |
---|
5 | // // |
---|
6 | // Institute of Microbiology (Technical University Munich) // |
---|
7 | // http://www.arb-home.de/ // |
---|
8 | // // |
---|
9 | // =============================================================== // |
---|
10 | |
---|
11 | #ifndef GB_MAIN_H |
---|
12 | #define GB_MAIN_H |
---|
13 | |
---|
14 | #ifndef GB_LOCAL_H |
---|
15 | #include "gb_local.h" |
---|
16 | #endif |
---|
17 | #ifndef GB_CB_H |
---|
18 | #include "gb_cb.h" |
---|
19 | #endif |
---|
20 | |
---|
21 | // ------------------------------ |
---|
22 | // forward declare types |
---|
23 | |
---|
24 | struct g_b_undo_mgr; |
---|
25 | struct gb_close_callback_list; |
---|
26 | struct gb_user; |
---|
27 | struct gb_project; |
---|
28 | struct gb_Key; |
---|
29 | struct gb_server_data; |
---|
30 | struct gb_hierarchy_callback_list; |
---|
31 | class gb_hierarchy_location; |
---|
32 | |
---|
33 | // -------------------------------------------------------------------------------- |
---|
34 | |
---|
35 | enum gb_open_types { |
---|
36 | gb_open_all = 0, |
---|
37 | gb_open_read_only_all = 16, |
---|
38 | gb_open_read_only_small = 17 |
---|
39 | }; |
---|
40 | |
---|
41 | struct gb_quick_save { |
---|
42 | char *quick_save_disabled; // if set, quick save is not possible and text describes reason why |
---|
43 | int last_index; |
---|
44 | |
---|
45 | gb_quick_save() : |
---|
46 | quick_save_disabled(NULp), |
---|
47 | last_index(0) |
---|
48 | {} |
---|
49 | }; |
---|
50 | |
---|
51 | // -------------------------------------------------------------------------------- |
---|
52 | |
---|
53 | #if defined(DEBUG) |
---|
54 | // #define GEN_CACHE_STATS // unit tests will fail if enabled |
---|
55 | #endif // DEBUG |
---|
56 | |
---|
57 | typedef uint16_t gb_cache_idx; |
---|
58 | |
---|
59 | struct gb_cache_entry; |
---|
60 | struct gb_cache : virtual Noncopyable { |
---|
61 | gb_cache_entry *entries; |
---|
62 | |
---|
63 | gb_cache_idx firstfree_entry; |
---|
64 | gb_cache_idx newest_entry; |
---|
65 | gb_cache_idx oldest_entry; |
---|
66 | |
---|
67 | size_t sum_data_size; |
---|
68 | size_t max_data_size; |
---|
69 | size_t big_data_min_size; |
---|
70 | |
---|
71 | #if defined(GEN_CACHE_STATS) |
---|
72 | GB_HASH *not_reused; // key = DB_path, value = number of cache entries not reused |
---|
73 | GB_HASH *reused; // key = DB_path, value = number of cache entries reused |
---|
74 | GB_HASH *reuse_sum; // key = DB_path, value = how often entries were reused |
---|
75 | #endif |
---|
76 | |
---|
77 | gb_cache(); |
---|
78 | ~gb_cache(); |
---|
79 | }; |
---|
80 | |
---|
81 | // -------------------------------------------------------------------------------- |
---|
82 | // root structure (one for each database) |
---|
83 | |
---|
84 | #define ALLOWED_KEYS 15000 |
---|
85 | #define ALLOWED_DATES 256 |
---|
86 | |
---|
87 | class GB_MAIN_TYPE : virtual Noncopyable { |
---|
88 | inline GB_ERROR start_transaction() __ATTR__USERESULT; |
---|
89 | GB_ERROR check_quick_save() const; |
---|
90 | GB_ERROR initial_client_transaction() __ATTR__USERESULT; |
---|
91 | |
---|
92 | int transaction_level; |
---|
93 | int aborted_transaction; |
---|
94 | |
---|
95 | bool i_am_server; |
---|
96 | |
---|
97 | struct callback_group : virtual Noncopyable { |
---|
98 | gb_hierarchy_callback_list *hierarchy_cbs; // defined hierarchy callbacks |
---|
99 | gb_pending_callbacks pending; // collect triggered callbacks (will be called by commit; discarded by abort) |
---|
100 | |
---|
101 | callback_group() : hierarchy_cbs(NULp) {} |
---|
102 | |
---|
103 | inline void add_hcb(const gb_hierarchy_location& loc, const TypedDatabaseCallback& dbcb); |
---|
104 | inline void remove_hcb(const gb_hierarchy_location& loc, const TypedDatabaseCallback& dbcb); |
---|
105 | inline void forget_hcbs(); |
---|
106 | |
---|
107 | void trigger(GBDATA *gbd, GB_CB_TYPE type, gb_callback_list *dataCBs); |
---|
108 | }; |
---|
109 | |
---|
110 | callback_group changeCBs; // all but GB_CB_DELETE |
---|
111 | callback_group deleteCBs; // GB_CB_DELETE |
---|
112 | |
---|
113 | friend class ArbDBWriter; |
---|
114 | |
---|
115 | public: |
---|
116 | |
---|
117 | gbcmc_comm *c_link; |
---|
118 | gb_server_data *server_data; |
---|
119 | GBCONTAINER *dummy_father; |
---|
120 | GBCONTAINER *root_container; |
---|
121 | GBCONTAINER *gb_key_data; |
---|
122 | char *path; |
---|
123 | gb_open_types opentype; |
---|
124 | char *disabled_path; |
---|
125 | int allow_corrupt_file_recovery; |
---|
126 | |
---|
127 | gb_quick_save qs; |
---|
128 | gb_cache cache; |
---|
129 | int compression_mask; |
---|
130 | |
---|
131 | int keycnt; // first non used key |
---|
132 | long sizeofkeys; // malloc size |
---|
133 | long first_free_key; // index of first gap |
---|
134 | gb_Key *keys; |
---|
135 | GB_HASH *key_2_index_hash; |
---|
136 | long key_clock; // trans. nr. of last change |
---|
137 | bool mapped; // true -> loaded via mapfile |
---|
138 | |
---|
139 | unsigned int last_updated; |
---|
140 | long last_saved_time; |
---|
141 | long last_saved_transaction; |
---|
142 | long last_main_saved_transaction; |
---|
143 | |
---|
144 | GB_UNDO_TYPE requested_undo_type; |
---|
145 | GB_UNDO_TYPE undo_type; |
---|
146 | |
---|
147 | g_b_undo_mgr *undo; |
---|
148 | |
---|
149 | char *dates[ALLOWED_DATES]; // @@@ saved to DB, but never used |
---|
150 | unsigned int security_level; |
---|
151 | long clock; |
---|
152 | GB_NUMHASH *remote_hash; |
---|
153 | |
---|
154 | gb_callback_list *close_callbacks; |
---|
155 | |
---|
156 | gb_user *users[GB_MAX_USERS]; // user 0 is server |
---|
157 | gb_user *this_user; |
---|
158 | |
---|
159 | // -------------------- |
---|
160 | |
---|
161 | private: |
---|
162 | GBCONTAINER*& gb_main_ref() { return root_container; } |
---|
163 | |
---|
164 | GB_ERROR check_saveable(const char *new_path, const char *flags) const; |
---|
165 | GB_ERROR check_quick_saveable(const char *new_path, const char *flags) const { |
---|
166 | GB_ERROR error = check_quick_save(); |
---|
167 | return error ? error : check_saveable(new_path, flags); |
---|
168 | } |
---|
169 | public: |
---|
170 | |
---|
171 | GB_MAIN_TYPE(const char *db_path); |
---|
172 | ~GB_MAIN_TYPE(); |
---|
173 | |
---|
174 | void free_all_keys(); |
---|
175 | void release_main_idx(); |
---|
176 | |
---|
177 | int get_transaction_level() const { return transaction_level; } |
---|
178 | |
---|
179 | GBDATA *gb_main() const { return (GBDATA*)root_container; } |
---|
180 | |
---|
181 | GB_ERROR login_remote(const char *db_path, const char *opent) __ATTR__USERESULT; |
---|
182 | |
---|
183 | inline GB_ERROR begin_transaction() __ATTR__USERESULT; |
---|
184 | inline GB_ERROR commit_transaction() __ATTR__USERESULT; |
---|
185 | inline GB_ERROR abort_transaction() __ATTR__USERESULT; |
---|
186 | |
---|
187 | inline GB_ERROR push_transaction() __ATTR__USERESULT; |
---|
188 | inline GB_ERROR pop_transaction() __ATTR__USERESULT; |
---|
189 | |
---|
190 | inline GB_ERROR no_transaction(); |
---|
191 | |
---|
192 | __ATTR__USERESULT GB_ERROR send_update_to_server(GBDATA *gbd) __ATTR__USERESULT; |
---|
193 | |
---|
194 | GB_ERROR save_quick(const char *refpath); |
---|
195 | |
---|
196 | GB_ERROR save_as(const char *as_path, const char *savetype); |
---|
197 | GB_ERROR save_quick_as(const char *as_path); |
---|
198 | |
---|
199 | GB_ERROR panic_save(const char *db_panic); |
---|
200 | |
---|
201 | void mark_as_server() { i_am_server = true; } |
---|
202 | |
---|
203 | bool is_server() const { return i_am_server; } |
---|
204 | bool is_client() const { return !is_server(); } |
---|
205 | |
---|
206 | void call_pending_callbacks(); |
---|
207 | |
---|
208 | bool has_pending_change_callback() const { return changeCBs.pending.pending(); } |
---|
209 | bool has_pending_delete_callback() const { return deleteCBs.pending.pending(); } |
---|
210 | |
---|
211 | GB_ERROR add_hierarchy_cb(const gb_hierarchy_location& loc, const TypedDatabaseCallback& dbcb); |
---|
212 | GB_ERROR remove_hierarchy_cb(const gb_hierarchy_location& loc, const TypedDatabaseCallback& dbcb); |
---|
213 | void forget_hierarchy_cbs(); |
---|
214 | |
---|
215 | inline void trigger_change_callbacks(GBDATA *gbd, GB_CB_TYPE type); |
---|
216 | void trigger_delete_callbacks(GBDATA *gbd); |
---|
217 | }; |
---|
218 | |
---|
219 | #else |
---|
220 | #error gb_main.h included twice |
---|
221 | #endif // GB_MAIN_H |
---|
222 | |
---|