Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / mgrs / template_mgr.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * $XConsortium: template_mgr.C /main/10 1996/10/03 18:50:20 drk $
25  *
26  * Copyright (c) 1992 HAL Computer Systems International, Ltd.
27  * All rights reserved.  Unpublished -- rights reserved under
28  * the Copyright Laws of the United States.  USE OF A COPYRIGHT
29  * NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
30  * OR DISCLOSURE.
31  * 
32  * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE
33  * SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.  USE,
34  * DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE
35  * PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS
36  * INTERNATIONAL, LTD.
37  * 
38  *                         RESTRICTED RIGHTS LEGEND
39  * Use, duplication, or disclosure by the Government is subject
40  * to the restrictions as set forth in subparagraph (c)(l)(ii)
41  * of the Rights in Technical Data and Computer Software clause
42  * at DFARS 252.227-7013.
43  *
44  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.
45  *                  1315 Dell Avenue
46  *                  Campbell, CA  95008
47  * 
48  */
49
50
51 #include "mgrs/template_mgr.h"
52
53 #include "object/root.h"
54 #include "object/oid.h"
55 #include "object/integer.h"
56 #include "object/pstring.h"
57 #include "object/compressed_pstring.h"
58 #include "object/tuple.h"
59 #include "object/short_list.h"
60 #include "object/cset.h"
61 #include "index/mphf_index.h"
62 #include "index/btree_index.h"
63 #include "index/dyn_memory_index.h"
64 #include "index/dyn_disk_index.h"
65 #include "object/dl_list_cell.h"
66 #include "object/dl_list.h"
67 #include "compression/zip.h"
68 #include "compression/huffman.h"
69 #include "compression/lzss.h"
70
71 #include "api/transaction.h"
72
73 extern memory_pool g_memory_pool;
74
75 #ifdef NMEMORY_MAPPED
76 #define CLASS_CODE_BYTES ll4(sizeof(c_code_t))
77 #else
78 #define CLASS_CODE_BYTES sizeof(c_code_t)
79 #endif
80
81 #define TEMP_OBJ_NUMS 18
82 static rootPtr template_obj_table[TEMP_OBJ_NUMS] ;
83
84
85 #ifdef C_API
86 buffer* cdr_io_buf_ptr = 0;
87 #define cdr_io_buf (*cdr_io_buf_ptr)
88 #else
89 static buffer cdr_io_buf(LBUFSIZ);
90 #endif
91
92
93 template_mgr_t::template_mgr_t() : v_template_objs(32801, 20)
94 {
95 #ifdef C_API
96    if ( cdr_io_buf_ptr == 0 )
97       cdr_io_buf_ptr = new buffer(LBUFSIZ); 
98 #endif
99
100    template_obj_table[0] = ::new compressed_pstring;
101    template_obj_table[1] = ::new oid;
102    template_obj_table[2] = ::new integer;
103    template_obj_table[3] = ::new pstring;
104    template_obj_table[4] = ::new tuple;
105    template_obj_table[5] = ::new oid_list;
106    template_obj_table[6] = ::new fast_mphf;
107    template_obj_table[7] = ::new inv_lists;
108    template_obj_table[8] = ::new mphf_index;
109    template_obj_table[9] = ::new btree_index;
110    template_obj_table[10] = ::new dyn_memory_index;
111    template_obj_table[11] = ::new dyn_disk_index;
112    template_obj_table[12] = ::new cset;
113    template_obj_table[13] = ::new short_list;
114    template_obj_table[14] = ::new dl_list_cell;
115    template_obj_table[15] = ::new dl_list;
116    template_obj_table[16] = ::new huff;
117    template_obj_table[17] = ::new lzss;
118
119    for ( int i=0; i<TEMP_OBJ_NUMS; i++ ) {
120       insert_template(template_obj_table[i]);
121    }
122 }
123
124 template_mgr_t::~template_mgr_t()
125 {
126    for ( int i=0; i<TEMP_OBJ_NUMS; i++ ) {
127       ::delete template_obj_table[i];
128    }
129
130 #ifdef C_API
131    delete cdr_io_buf_ptr;
132 #endif
133 }
134
135
136 root* template_mgr_t::look_up(c_code_t c_code)
137 {
138    data_t key_data(c_code, 0);
139    if ( v_template_objs.member(key_data) == true &&
140         long(key_data.dt) != -1 ) {
141       return (root*)(key_data.dt);
142    } else {
143       return 0;
144   }
145 }
146
147
148 c_code_t 
149 template_mgr_t::_peek_slot(abs_storage* store, mmdb_pos_t pos, 
150                            char*& z, int& len)
151 {
152 //debug(cerr, pos);
153
154    if ( store == 0 || store -> OK() == false ) {
155       throw(stringException("template_mgr_t::_peek_obj() store in bad shape"));
156    }
157       
158 //first read in the oid_t string.
159
160    if ( store -> get_str_ptr(pos, z, len) != 0 ) {
161       throw(stringException("_peek_obj(): can't get oid_t string"));
162    }
163
164 //debug(cerr, len);
165 /*cerr << "len=" << len << endl;
166 for (int i=0; i<len; i++)
167    cerr << int(z[i]) << " ";
168 cerr << "\n";
169 */
170
171
172    if ( len < (int) CLASS_CODE_BYTES || z == 0 )
173       throw(stringException("_peek_obj(): corrupted data"));
174
175    c_code_t class_code; 
176    memcpy((char*)&class_code, z, CLASS_CODE_BYTES);
177 //debug(cerr, class_code);
178  
179 #ifdef PORTABLE_DB
180    if ( store -> swap_order() == true ) {
181 //MESSAGE(cerr, "swap class code order");
182       ORDER_SWAP_USHORT(class_code);
183    }
184 #endif
185
186 //debug(cerr, class_code);
187
188    return class_code;
189 }
190
191 c_code_t template_mgr_t::peek_slot(abs_storage* store, mmdb_pos_t pos)
192 {
193    char* z = 0; int len = 0;
194    c_code_t class_code = _peek_slot(store, pos, z, len);
195    RESET_BIT(class_code, CDR_FLAG);
196    return class_code;
197 }
198
199 /******************************************************/
200 // return an object in x. The object is fetched from
201 // store 'store' at location 'pos'.
202 // If the object has been previously deleted, an
203 // exception will be thrown. 
204 /******************************************************/
205 Boolean 
206 template_mgr_t::init_obj(abs_storage* store, mmdb_pos_t pos, root*& x)
207 {
208 //debug(cerr, store -> my_name());
209 //debug(cerr, pos);
210
211    x = 0;
212
213    char* z = 0; int len = 0;
214    c_code_t class_code = _peek_slot(store, pos, z, len);
215 #ifdef DEBUG
216    {
217      char* dbg_char_ptr;
218      int   dbg_int;
219      store->get_str_ptr(pos, dbg_char_ptr, dbg_int);
220      fprintf(stderr, "init_obj ptr=0x%lx len=%d\n", (long)dbg_char_ptr,dbg_int);
221    }
222 #endif
223
224    if ( class_code == 0 ) 
225       throw(stringException("init_obj(): class code == 0 "));
226
227    Boolean compacted_disk_rep = 
228          ( BIT_TEST(class_code, CDR_FLAG) ) ? true : false;
229
230 //debug(cerr, int(compacted_disk_rep));
231
232    RESET_BIT(class_code, CDR_FLAG);
233
234 //debug(cerr, class_code);
235 //if ( pos == 16385 ) {
236 //MESSAGE(cerr, "STOP:");
237 //}
238
239    rootPtr object_template = look_up(class_code);
240
241    if ( object_template == 0 ) {
242       debug(cerr, class_code);
243       debug(cerr, store -> my_name());
244       throw(stringException("init_obj(): can't find object template"));
245    }
246
247    /*****************************************/
248    // make sure that the string existing on 
249    // the store is of sufficient length 
250    /*****************************************/
251    
252    int obj_len = len - CLASS_CODE_BYTES;
253
254    switch ( compacted_disk_rep ) {
255
256      case true:
257       {
258
259 ////////////////////////////////////
260 // compute and cache the cdr size
261 ////////////////////////////////////
262        if ( object_template -> get_cdr_size() == 0 ) {
263             cdr_io_buf.reset();
264             object_template -> cdrOut(cdr_io_buf);
265             object_template -> set_cdr_size(cdr_io_buf.content_sz());
266        }
267
268
269 /////////////////
270 // safety check
271 /////////////////
272 #ifdef DEBUG
273        int cdr_sz = object_template -> get_cdr_size();
274
275        if ( obj_len != cdr_sz ) {
276           debug(cerr, obj_len);
277           debug(cerr, cdr_sz);
278           debug(cerr, *(c_code_t*)z);
279           throw(stringException("corrupted data"));
280        }
281 #endif
282        break;
283       }
284
285      case false:
286        if ( obj_len != object_template -> mem_sizeof() ) {
287           debug(cerr, obj_len);
288           debug(cerr, object_template -> mem_sizeof());
289           debug(cerr, *(c_code_t*)z);
290           throw(stringException("corrupted data"));
291        }
292        break;
293    }
294
295     if ( g_transac ) {
296         g_transac -> book(store);
297     }
298
299 //debug(cerr, int(store));
300 //debug(cerr, pos);
301 //debug(cerr, class_code);
302
303    persistent_info pinfo;
304
305    pinfo.storage = store;
306    pinfo.position = pos;
307    pinfo.persistent = true;
308    pinfo.old_object = true;
309    pinfo.class_code = class_code;
310
311
312 #ifdef MEMORY_MAPPED
313    x = object_template -> cast_to( z + CLASS_CODE_BYTES );
314 #else
315    //char* p = g_memory_pool.alloc( object_template -> mem_sizeof());
316    char* p = new char[object_template -> mem_sizeof()];
317
318 //MESSAGE(cerr, "template mgr: init case(), new char array");
319 //debug(cerr, (void*)p);
320
321    switch ( compacted_disk_rep ) {
322
323      case true:
324        memset((char*)p, char(0), object_template -> mem_sizeof());
325        break;
326      case false:
327        memcpy((char*)p, z + CLASS_CODE_BYTES, obj_len);
328        break;
329    }
330
331    x = object_template -> cast_to( p );
332 #endif
333
334    x -> init_persistent_info( &pinfo );
335
336    switch ( compacted_disk_rep ) {
337      case true:
338        {
339        buffer buf(0);
340        buf.set_chunk(z+CLASS_CODE_BYTES, obj_len);
341        buf.set_content_sz(obj_len);
342
343 #ifdef PORTABLE_DB
344        buf.set_swap_order(store -> swap_order());
345 #endif
346
347        x -> cdrIn(buf);
348        }
349        break;
350      default:
351        break;
352    }
353
354    x -> set_mode(UPDATE, false);
355
356 //x -> my_oid().asciiOut(cerr); cerr << "\n";
357 //MESSAGE(cerr, "template_mgr_t::init_obj() done");
358    return true;
359
360 }
361
362 Boolean
363 template_mgr_t::commit_obj(abs_storage* store, root* obj_ptr)
364 {
365    if ( store && obj_ptr && 
366         obj_ptr -> get_mode(UPDATE) == true
367    ) {
368
369 /*
370 MESSAGE(cerr, "COMMIT OBJECT");
371 debug(cerr, obj_ptr -> my_oid());
372 */
373
374 ////////////////////////////////
375 // update the object disk copy.
376 ////////////////////////////////
377
378       switch ( obj_ptr -> get_mode(CDR) ) {
379      
380          case true:
381
382 #ifdef PORTABLE_DB
383              cdr_io_buf.set_swap_order(store -> swap_order());
384 #endif
385
386             cdr_io_buf.reset();
387             obj_ptr -> cdrOut(cdr_io_buf);
388
389 //debug(cerr, cdr_io_buf);
390 //debug(cerr, cdr_io_buf.content_sz());
391
392             store -> 
393                 updateString(mmdb_pos_t(obj_ptr -> my_oid().icode()), 
394                              cdr_io_buf.get_base(),
395                              cdr_io_buf.content_sz(),
396                              CLASS_CODE_BYTES 
397                             );
398    
399             break;
400    
401         case false:
402
403             store -> 
404                 updateString(mmdb_pos_t(obj_ptr -> my_oid().icode()), (char*)obj_ptr,
405                              obj_ptr -> mem_sizeof(), 
406                              CLASS_CODE_BYTES
407                             );
408              break;
409       }
410
411       obj_ptr -> set_mode(UPDATE, false);
412      
413    }
414
415    return true;
416 }
417
418 Boolean
419 template_mgr_t::quit_obj(abs_storage* store, root* obj_ptr)
420 {
421 //MESSAGE(cerr, "template_mgr_t::quit_obj()");
422 //debug(cerr, (void*)obj_ptr);
423    commit_obj(store, obj_ptr);
424
425    if ( obj_ptr ) 
426       obj_ptr -> f_oid.become(ground);
427
428    delete obj_ptr;
429
430    return true;
431 }
432
433 /******************************************************/
434 // return an object in x. The object is
435 // saved on the store 'store'. Its location is the
436 // i_code of the object.
437 /******************************************************/
438
439 Boolean 
440 template_mgr_t::create_obj(abs_storage* store, c_code_t class_code, root*& new_obj)
441 {
442 //MESSAGE(cerr, "Create obj case");
443 //debug(cerr, class_code);
444
445 #ifdef DEBUG
446     fprintf(stderr, "create_obj class_code=%d\n", class_code);
447 #endif
448
449     /*****************************************/
450     // Can we find a matched template object?
451     // The match is based on the class code.
452     /*****************************************/
453     root* object_template = look_up(class_code);
454
455     if ( object_template == 0 ) {
456         debug(cerr, class_code);
457         throw(stringException("get_obj(): unknown object instance"));
458     }
459
460     /*****************************************/
461     // ask the template to create a new object
462     // on store 'store'.
463     /*****************************************/
464
465     char* store_str_ptr = 0;
466
467 #ifdef COMPACTED_DISK_REP
468          
469     if ( object_template -> get_cdr_size() == 0 ) {
470 //////////////////////////////////
471 // compute and cache the cdr_size  
472 //////////////////////////////////
473       cdr_io_buf.reset();
474       object_template -> cdrOut(cdr_io_buf);
475       object_template -> set_cdr_size(cdr_io_buf.content_sz());
476     }
477
478     int disk_obj_len = object_template -> get_cdr_size();
479
480 #else
481     int disk_obj_len = object_template -> mem_sizeof();
482 #endif
483
484 /*
485 MESSAGE(cerr, "to allocate string");
486 debug(cerr, disk_obj_len);
487 debug(cerr, CLASS_CODE_BYTES);
488 */
489
490     if ( g_transac ) {
491         g_transac -> book(store);
492     }
493
494     persistent_info pinfo;
495
496 #ifdef C_API
497     store -> allocString (pinfo.position,
498                                 disk_obj_len + CLASS_CODE_BYTES,
499                                 store_str_ptr, spointer_t::IS_OBJECT
500                          );
501 #else
502     store -> allocString (pinfo.position,
503                                 disk_obj_len + CLASS_CODE_BYTES,
504                                 store_str_ptr, spointer_t::IS_OBJECT
505                          );
506 #ifdef DEBUG
507     {
508       char* dbg_char_ptr;
509       int   dbg_int;
510       store->get_str_ptr(pinfo.position, dbg_char_ptr, dbg_int);
511       fprintf(stderr, "create_obj ptr=0x%lx len=%d\n",
512                                         (long)dbg_char_ptr, dbg_int);
513     }
514 #endif
515 #endif
516
517 #ifdef COMPACTED_DISK_REP
518     SET_BIT(class_code, CDR_FLAG); 
519 #endif
520
521 //debug(cerr, pinfo.position);
522
523 #ifdef PORTABLE_DB
524    if ( store -> swap_order() == true ) {
525 //MESSAGE(cerr, "switch class code in create_obj");
526        c_code_t x = class_code;
527 //debug(cerr, x);
528        ORDER_SWAP_USHORT(x);
529 //debug(cerr, x);
530        memcpy(store_str_ptr, (char*)&x, sizeof(x));
531    } else {
532 //MESSAGE(cerr, "do not switch class code in create_obj");
533 //debug(cerr, class_code);
534        memcpy(store_str_ptr, (char*)&class_code, sizeof(class_code));
535    }
536 #else
537    memcpy(store_str_ptr, (char*)&class_code, sizeof(class_code));
538 #endif
539
540 //debug(cerr, class_code);
541 //debug(cerr, long(store_str_ptr));
542 //for ( int i=0; i<sizeof(class_code); i++ )
543 //   cerr << int(store_str_ptr[i]) << " ";
544 //cerr << endl;
545
546 #ifdef COMPACTED_DISK_REP
547     RESET_BIT(class_code, CDR_FLAG); 
548 #endif
549
550     pinfo.storage = store;
551     pinfo.old_object = false;
552     pinfo.persistent = true;
553     pinfo.class_code = class_code;
554
555 #ifdef MEMORY_MAPPED
556     new_obj = object_template -> cast_to( store_str_ptr + CLASS_CODE_BYTES);
557 #else
558
559 //MESSAGE(cerr, "to clean mem allocated");
560
561     int mem_obj_len = object_template -> mem_sizeof();
562
563     //char* p = g_memory_pool.alloc(mem_obj_len);
564     char* p = new char[mem_obj_len];
565
566 //MESSAGE(cerr, "template mgr: create case(), new char array");
567 //debug(cerr, (void*)p);
568
569     memset(p, char(0), mem_obj_len);
570     new_obj = object_template -> cast_to( p );
571
572 #endif
573
574    new_obj -> init_persistent_info( &pinfo );
575
576 #ifdef COMPACTED_DISK_REP
577     new_obj -> set_mode(CDR, true);
578 #else
579     new_obj -> set_mode(CDR, false);
580 #endif
581
582     new_obj -> set_mode(OLD_OBJECT, true);
583     new_obj -> set_mode(UPDATE, true);
584     new_obj -> set_mode(HEALTH, true);
585
586 //debug(cerr, int(new_obj -> get_mode(BASE_DATA_INITED)));
587 //debug(cerr, int(new_obj -> get_mode(PERSISTENT)));
588
589 /*
590 MESSAGE(cerr, "oid of the new created obj:");
591 debug(cerr, class_code);
592 cerr << "class_code=" << class_code ;
593 cerr <<  ", location=";
594 cerr << PAGE_ID((new_obj -> my_oid()).icode(), 8192) << ".";
595 cerr << PAGE_IDX((new_obj -> my_oid()).icode(), 8192) << "\n";
596 */
597
598
599 //MESSAGE(cerr, "create_obj done()");
600
601     return true;
602 }
603
604 Boolean template_mgr_t::destroy_obj(abs_storage* store, root* x)
605 {
606    if ( store && x ) {
607 //MESSAGE(cerr, "destroy_obj()");
608 //debug(cerr, x -> my_oid());
609       store -> deleteString( mmdb_pos_t(x -> my_oid().icode()) );
610       x -> f_oid.become(ground);
611 //MESSAGE(cerr, "destroy_obj() done");
612    }
613
614    return true;
615 }
616
617 Boolean template_mgr_t::insert_template(root* tmt)
618 {
619     if ( tmt == 0 ) return true;
620
621     c_code_t class_code = tmt -> my_oid().ccode();
622
623     if ( look_up(class_code) == 0 ) {
624        data_t key_data(class_code, tmt);
625        v_template_objs.insert(key_data);
626     } 
627
628     return true;
629 }
630