hp_open.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16. /* open a heap-database */
  17. #include "heapdef.h"
  18. #ifdef VMS
  19. #include "hp_static.c" /* Stupid vms-linker */
  20. #endif
  21. static void init_block(HP_BLOCK *block,uint reclength,ulong min_records,
  22.        ulong max_records);
  23. /* open a heap database. */
  24. HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef,
  25.    uint reclength, ulong max_records, ulong min_records)
  26. {
  27.   uint i,j,key_segs,max_length,length;
  28.   HP_INFO *info;
  29.   HP_SHARE *share;
  30.   HP_KEYSEG *keyseg;
  31.   DBUG_ENTER("heap_open");
  32.   pthread_mutex_lock(&THR_LOCK_heap);
  33.   if (!(share=_hp_find_named_heap(name)))
  34.   {
  35.     DBUG_PRINT("info",("Initializing new table"));
  36.     for (i=key_segs=max_length=0 ; i < keys ; i++)
  37.     {
  38.       key_segs+= keydef[i].keysegs;
  39.       bzero((char*) &keydef[i].block,sizeof(keydef[i].block));
  40.       for (j=length=0 ; j < keydef[i].keysegs; j++)
  41. length+=keydef[i].seg[j].length;
  42.       keydef[i].length=length;
  43.       if (length > max_length)
  44. max_length=length;
  45.     }
  46.     if (!(share = (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+
  47.        keys*sizeof(HP_KEYDEF)+
  48.        key_segs*sizeof(HP_KEYSEG),
  49.        MYF(MY_ZEROFILL))))
  50.     {
  51.       pthread_mutex_unlock(&THR_LOCK_heap);
  52.       DBUG_RETURN(0);
  53.     }
  54.     share->keydef=(HP_KEYDEF*) (share+1);
  55.     keyseg=(HP_KEYSEG*) (share->keydef+keys);
  56.     init_block(&share->block,reclength+1,min_records,max_records);
  57. /* Fix keys */
  58.     memcpy(share->keydef,keydef,(size_t) (sizeof(keydef[0])*keys));
  59.     for (i=0 ; i < keys ; i++)
  60.     {
  61.       share->keydef[i].seg=keyseg;
  62.       memcpy(keyseg,keydef[i].seg,
  63.      (size_t) (sizeof(keyseg[0])*keydef[i].keysegs));
  64.       keyseg+=keydef[i].keysegs;
  65.       init_block(&share->keydef[i].block,sizeof(HASH_INFO),min_records,
  66.  max_records);
  67.     }
  68.     share->min_records=min_records;
  69.     share->max_records=max_records;
  70.     share->data_length=share->index_length=0;
  71.     share->reclength=reclength;
  72.     share->blength=1;
  73.     share->keys=keys;
  74.     share->max_key_length=max_length;
  75.     share->changed=0;
  76.     if (!(share->name=my_strdup(name,MYF(0))))
  77.     {
  78.       my_free((gptr) share,MYF(0));
  79.       pthread_mutex_unlock(&THR_LOCK_heap);
  80.       DBUG_RETURN(0);
  81.     }
  82. #ifdef THREAD
  83.     thr_lock_init(&share->lock);
  84.     VOID(pthread_mutex_init(&share->intern_lock,NULL));
  85. #endif
  86.     share->open_list.data=(void*) share;
  87.     heap_share_list=list_add(heap_share_list,&share->open_list);
  88.   }
  89.   if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO)+
  90.   share->max_key_length,
  91.   MYF(MY_ZEROFILL))))
  92.   {
  93.     pthread_mutex_unlock(&THR_LOCK_heap);
  94.     DBUG_RETURN(0);
  95.   }
  96.   share->open_count++;
  97. #ifdef THREAD
  98.   thr_lock_data_init(&share->lock,&info->lock,NULL);
  99. #endif
  100.   info->open_list.data=(void*) info;
  101.   heap_open_list=list_add(heap_open_list,&info->open_list);
  102.   pthread_mutex_unlock(&THR_LOCK_heap);
  103.   info->s=share;
  104.   info->lastkey=(byte*) (info+1);
  105.   info->mode=mode;
  106.   info->current_record= (ulong) ~0L; /* No current record */
  107.   info->current_ptr=0;
  108.   info->current_hash_ptr=0;
  109.   info->lastinx=  info->errkey= -1;
  110.   info->update=0;
  111. #ifndef DBUG_OFF
  112.   info->opt_flag=READ_CHECK_USED; /* Check when changing */
  113. #endif
  114.   DBUG_PRINT("exit",("heap: %lx  reclength: %d  records_in_block: %d",
  115.      info,share->reclength,share->block.records_in_block));
  116.   DBUG_RETURN(info);
  117. } /* heap_open */
  118. /* map name to a heap-nr. If name isn't found return 0 */
  119. HP_SHARE *_hp_find_named_heap(const char *name)
  120. {
  121.   LIST *pos;
  122.   HP_SHARE *info;
  123.   DBUG_ENTER("heap_find");
  124.   DBUG_PRINT("enter",("name: %s",name));
  125.   for (pos=heap_share_list ; pos ; pos=pos->next)
  126.   {
  127.     info=(HP_SHARE*) pos->data;
  128.     if (!strcmp(name,info->name))
  129.     {
  130.       DBUG_PRINT("exit",("Old heap_database: %lx",info));
  131.       DBUG_RETURN(info);
  132.     }
  133.   }
  134.   DBUG_RETURN((HP_SHARE *)0);
  135. }
  136. static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
  137.        ulong max_records)
  138. {
  139.   uint i,recbuffer,records_in_block;
  140.   max_records=max(min_records,max_records);
  141.   if (!max_records)
  142.     max_records=1000; /* As good as quess as anything */
  143.   recbuffer=(uint) (reclength+sizeof(byte**)-1) & ~(sizeof(byte**)-1);
  144.   records_in_block=max_records/10;
  145.   if (records_in_block < 10 && max_records)
  146.     records_in_block=10;
  147.   if (!records_in_block || records_in_block*recbuffer >
  148.       (my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
  149.     records_in_block=(my_default_record_cache_size-sizeof(HP_PTRS)*
  150.       HP_MAX_LEVELS)/recbuffer+1;
  151.   block->records_in_block=records_in_block;
  152.   block->recbuffer=recbuffer;
  153.   block->last_allocated= 0L;
  154.   for (i=0 ; i <= HP_MAX_LEVELS ; i++)
  155.     block->level_info[i].records_under_level=
  156.       (!i ? 1 : i == 1 ? records_in_block :
  157.        HP_PTRS_IN_NOD * block->level_info[i-1].records_under_level);
  158. }