CUBRID Engine  latest
load_object_table.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * load_object_table.c - the object table for the loader
21  */
22 
23 #include "config.h"
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "db.h"
30 #include "load_object_table.h"
31 #include "memory_alloc.h"
32 #include "message_catalog.h"
33 #include "oid.h"
34 #include "porting.h"
35 #include "utility.h"
36 #include "work_space.h"
37 
39 
40 /*
41  * otable_find_class - Locate the class table entry for a class.
42  * return: class table
43  * class(in): class object
44  * Note:
45  * If one is not already on the list, a new one is created, added
46  * to the list and returned.
47  */
50 {
51  CLASS_TABLE *table = Classes;
52 
53  while (table != NULL && table->class_ != class_)
54  {
55  table = table->next;
56  }
57  if (table == NULL)
58  {
59  table = (CLASS_TABLE *) malloc (sizeof (CLASS_TABLE));
60  if (table == NULL)
61  {
63  }
64  else
65  {
66  table->next = Classes;
67  Classes = table;
68  table->class_ = class_;
69  table->instances = NULL;
70  table->count = 0;
71  table->presize = 0;
72  table->total_inserts = 0;
73  }
74  }
75 
76  return (table);
77 }
78 
79 /*
80  * flush_class_tables - Free storage for all the class tables.
81  * return: void
82  */
83 static void
85 {
86  CLASS_TABLE *table, *next;
87 
88  for (table = Classes, next = NULL; table != NULL; table = next)
89  {
90  next = table->next;
91  if (table->instances)
92  {
93  free_and_init (table->instances);
94  }
95  free_and_init (table);
96  }
97  Classes = NULL;
98 }
99 
100 /*
101  * init_instance_table - Initialized the contents of an instance array
102  * within a class table.
103  * return: none
104  * table(out): class table
105  */
106 static void
108 {
109  int i;
110 
111  for (i = 0; i < table->count; i++)
112  {
113  table->instances[i].flags = 0;
114  OID_SET_NULL (&(table->instances[i].oid));
115  }
116 }
117 
118 /*
119  * realloc_instance_table - Extends the instance array within a CLASS_TABLE.
120  * return: NO_ERROR if successful, error code otherwise
121  * table(in/out): class table to extend
122  * newcount(in): new size of the instance table
123  */
124 static int
125 realloc_instance_table (CLASS_TABLE * table, int newcount)
126 {
127  INST_INFO *tmp_inst_info;
128  int i;
129 
130  /*
131  * only do this if the new count is larger than the existing
132  * table, shouldn't see this
133  */
134  if (newcount > table->count)
135  {
136  tmp_inst_info = (INST_INFO *) realloc (table->instances, newcount * sizeof (INST_INFO));
137  if (tmp_inst_info == NULL)
138  {
140  return er_errid ();
141  }
142 
143  for (i = table->count; i < newcount; i++)
144  {
145  tmp_inst_info[i].flags = 0;
146  OID_SET_NULL (&(tmp_inst_info[i].oid));
147  }
148 
149  table->instances = tmp_inst_info;
150  table->count = newcount;
151  }
152  return NO_ERROR;
153 }
154 
155 /*
156  * grow_instance_table - extends the instance array in a CLASS_TABLE to be
157  * at least as large as the instance id given.
158  * return: NO_ERROR if successful, error code otherwise
159  * table(out): class table
160  * id(in): instance id of interest
161  */
162 static int
164 {
165  return realloc_instance_table (table, id + 1000);
166 }
167 
168 /*
169  * otable_find - Searches the class table for an instance with the given id.
170  * return: instance info structure
171  * table(in): class table
172  * id(in): instance id
173  */
174 INST_INFO *
175 otable_find (CLASS_TABLE * table, int id)
176 {
177  if (table->count > id && table->instances[id].flags)
178  {
179  return &(table->instances[id]);
180  }
181  return NULL;
182 }
183 
184 /*
185  * otable_insert - This inserts a new entry in the instance array of a class
186  * table.
187  * return: NO_ERROR if successful, error code otherwise
188  * table(out): class table
189  * instance(in): instance OID
190  * id(in): instance id number
191  */
192 int
193 otable_insert (CLASS_TABLE * table, OID * instance, int id)
194 {
195  int error = NO_ERROR;
196  INST_INFO *inst;
197 
198  if (id >= table->count)
199  {
200  error = grow_instance_table (table, id);
201  }
202 
203  if (error == NO_ERROR)
204  {
205  inst = &table->instances[id];
206  if (inst->flags & INST_FLAG_INSERTED)
207  /* lame, should pass in a stream for this */
209  id, db_get_class_name (table->class_));
210 
211  inst->oid = *instance;
212  inst->flags = INST_FLAG_INSERTED;
213  }
214  return error;
215 }
216 
217 /*
218  * otable_reserve - This is used to reserve an element for this instance id.
219  * return: NO_ERROR if successful, error code otherwise
220  * table(out): class table
221  * instance(in): instance OID
222  * id(in): instance id
223  * Note:
224  * This is exactly the same as otable_insert except that the
225  * instance element is flagged with INST_FLAG_RESERVED.
226  */
227 int
229 {
230  int error = NO_ERROR;
231  INST_INFO *inst;
232 
233  if (id >= table->count)
234  {
235  error = grow_instance_table (table, id);
236  }
237 
238  if (error == NO_ERROR)
239  {
240  inst = &table->instances[id];
241  if (inst->flags)
242  {
243  /* should pass in an appropriate stream here */
244  if (inst->flags & INST_FLAG_INSERTED)
246  id, db_get_class_name (table->class_));
247  else
248  fprintf (stdout,
250  db_get_class_name (table->class_));
251  }
252  else
253  {
254  inst->oid = *instance;
255  inst->flags = INST_FLAG_RESERVED;
256  }
257  }
258  return error;
259 }
260 
261 /*
262  * otable_class_att_ref - This is used to mark an instance to indicate it is
263  * referenced by a class attribute. The instance element is flagged with
264  * INST_FLAG_CLASS_ATT.
265  * return: void
266  * inst(out): instance info
267  * Note:
268  * This is used by the loader to mark instances that should not be culled
269  * until commit since they are pointed to directly by a class attribute.
270  */
271 void
273 {
274  if (inst)
275  {
276  inst->flags = inst->flags | INST_FLAG_CLASS_ATT;
277  }
278  return;
279 }
280 
281 /*
282  * otable_update - This is used to mark an existing instance element in a
283  * class table as being inserted.
284  * return: NO_ERROR
285  * table(out): class table
286  * id(in): instance id
287  */
288 int
289 otable_update (CLASS_TABLE * table, int id)
290 {
291  if (table->count > id)
292  {
294  }
295  return NO_ERROR;
296 }
297 
298 /*
299  * otable_map_reserved - maps over all the reserved elements in the class
300  * table and calls the supplied function for each one.
301  * return: NO_ERROR if successful, error code otherwise
302  * mapfunc(in): function to call
303  * stop_on_error(in): if set, it stops mapping with given func
304  * Note:
305  * THe function is passed the class pointer and the instance OID.
306  */
307 int
308 otable_map_reserved (OTABLE_MAPFUNC mapfunc, int stop_on_error)
309 {
310  int error = NO_ERROR;
311  CLASS_TABLE *table;
312  int i;
313 
314  for (table = Classes; table != NULL && error == NO_ERROR; table = table->next)
315  {
316  for (i = 0; i < table->count; i++)
317  {
318  if (table->instances[i].flags & INST_FLAG_RESERVED)
319  {
320  error = (*mapfunc) (table, &(table->instances[i].oid));
321  if (!stop_on_error)
322  {
323  error = NO_ERROR;
324  }
325  }
326  }
327  }
328  return error;
329 }
330 
331 /*
332  * otable_set_presize - set the estimated instance table size to a specific
333  * value.
334  * return: void
335  * table(out): class table
336  * id(in): estimated size
337  * Note:
338  * This will be used later by otable_prepare to allocate the
339  * actual instance table.
340  * Note that the size passed here is an instance id NOT a table size.
341  * The instance id's are used to index the table so the actual table
342  * size must be 1+ the maximum instance id.
343  */
344 void
346 {
347  if (table != NULL && (id + 1) > table->presize)
348  {
349  table->presize = id + 1;
350  }
351 }
352 
353 /*
354  * otable_init - initialize the class table module
355  * return: void
356  */
357 int
359 {
360  Classes = NULL;
361  return NO_ERROR;
362 }
363 
364 /*
365  * otable_prepare - set up the instance tables
366  * return: NO_ERROR if successful, error code otherwise
367  * Note:
368  * This will be called after the syntax check to set up the instance
369  * tables. During the syntax check we will have built the load_Classes
370  * list and incremented the presize field so we now know exactly
371  * how many instances to expect.
372  *
373  * This was originally written to allow the instance tables to have
374  * been previously allocated either as part of the original initialization
375  * with Estimated_size or incrementally during the syntax check.
376  * This is no longer done so the grow_instance_table function above
377  * should never get called. We now always perform a syntax check
378  * and use the presize calculation to allocate the tables of exactly
379  * the right size. This is important for performance.
380  */
381 int
383 {
384  int error = NO_ERROR;
385  CLASS_TABLE *table;
386 
387  for (table = Classes; table != NULL && !error; table = table->next)
388  {
389  /*
390  * If we already have an instance table, initialize the fields it
391  * contains. This shouldn't be necessary.
392  */
393  init_instance_table (table);
394 
395  /* Allocate the table according to the presize count */
396  error = realloc_instance_table (table, table->presize);
397  }
398  return error;
399 }
400 
401 /*
402  * otable_final - shutdown the class table module
403  * return: void
404  */
405 void
407 {
409 }
#define INST_FLAG_RESERVED
#define NO_ERROR
Definition: error_code.h:46
#define ER_LDR_MEMORY_ERROR
Definition: error_code.h:656
int otable_init(void)
const char * db_get_class_name(DB_OBJECT *class_)
Definition: db_info.c:608
INST_INFO * instances
static int realloc_instance_table(CLASS_TABLE *table, int newcount)
void otable_final(void)
#define OID_SET_NULL(oidp)
Definition: oid.h:85
int otable_prepare(void)
int er_errid(void)
CLASS_TABLE * Classes
int otable_reserve(CLASS_TABLE *table, OID *instance, int id)
int otable_insert(CLASS_TABLE *table, OID *instance, int id)
struct class_table * next
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
#define INST_FLAG_CLASS_ATT
void otable_class_att_ref(INST_INFO *inst)
CLASS_TABLE * otable_find_class(MOP class_)
#define NULL
Definition: freelistheap.h:34
int(* OTABLE_MAPFUNC)(CLASS_TABLE *class_, OID *oid)
#define INST_FLAG_INSERTED
static int grow_instance_table(CLASS_TABLE *table, int id)
INST_INFO * otable_find(CLASS_TABLE *table, int id)
static void error(const char *msg)
Definition: gencat.c:331
entry_workpool * instance
#define ARG_FILE_LINE
Definition: error_manager.h:44
int otable_map_reserved(OTABLE_MAPFUNC mapfunc, int stop_on_error)
#define free_and_init(ptr)
Definition: memory_alloc.h:147
void otable_set_presize(CLASS_TABLE *table, int id)
int i
Definition: dynamic_load.c:954
char * msgcat_message(int cat_id, int set_id, int msg_id)
static void init_instance_table(CLASS_TABLE *table)
static void flush_class_tables()
int otable_update(CLASS_TABLE *table, int id)
#define MSGCAT_CATALOG_UTILS