1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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; version 2 of the License. 6 7 This program is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU General Public License for more details. 11 12 You should have received a copy of the GNU General Public License 13 along with this program; if not, write to the Free Software 14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ 15 16 /* open a heap-database */ 17 18 #include "heapdef.h" 19 #include "my_sys.h" 20 21 /* 22 Open heap table based on HP_SHARE structure 23 24 NOTE 25 This doesn't register the table in the open table list. 26 */ 27 28 HP_INFO *heap_open_from_share(HP_SHARE *share, int mode) 29 { 30 HP_INFO *info; 31 DBUG_ENTER("heap_open_from_share"); 32 33 if (!(info= (HP_INFO*) my_malloc(sizeof(HP_INFO) + 34 2 * share->max_key_length, 35 MYF(MY_ZEROFILL + 36 (share->internal ? 37 MY_THREAD_SPECIFIC : 0))))) 38 { 39 DBUG_RETURN(0); 40 } 41 share->open_count++; 42 thr_lock_data_init(&share->lock,&info->lock,NULL); 43 info->s= share; 44 info->lastkey= (uchar*) (info + 1); 45 info->recbuf= (uchar*) (info->lastkey + share->max_key_length); 46 info->mode= mode; 47 info->current_record= (ulong) ~0L; /* No current record */ 48 info->lastinx= info->errkey= -1; 49 #ifndef DBUG_OFF 50 info->opt_flag= READ_CHECK_USED; /* Check when changing */ 51 #endif 52 DBUG_PRINT("exit",("heap: %p reclength: %d records_in_block: %lu", 53 info, share->reclength, 54 share->block.records_in_block)); 55 DBUG_RETURN(info); 56 } 57 58 59 /* 60 Open heap table based on HP_SHARE structure and register it 61 */ 62 63 HP_INFO *heap_open_from_share_and_register(HP_SHARE *share, int mode) 64 { 65 HP_INFO *info; 66 DBUG_ENTER("heap_open_from_share_and_register"); 67 68 mysql_mutex_lock(&THR_LOCK_heap); 69 if ((info= heap_open_from_share(share, mode))) 70 { 71 info->open_list.data= (void*) info; 72 heap_open_list= list_add(heap_open_list,&info->open_list); 73 /* Unpin the share, it is now pinned by the file. */ 74 share->open_count--; 75 } 76 mysql_mutex_unlock(&THR_LOCK_heap); 77 DBUG_RETURN(info); 78 } 79 80 81 /** 82 Dereference a HEAP share and free it if it's not referenced. 83 We don't check open_count for internal tables since they 84 are always thread-local, i.e. referenced by a single thread. 85 */ 86 void heap_release_share(HP_SHARE *share, my_bool internal_table) 87 { 88 /* Couldn't open table; Remove the newly created table */ 89 if (internal_table) 90 hp_free(share); 91 else 92 { 93 mysql_mutex_lock(&THR_LOCK_heap); 94 if (--share->open_count == 0) 95 hp_free(share); 96 mysql_mutex_unlock(&THR_LOCK_heap); 97 } 98 } 99 100 /* 101 Open heap table based on name 102 103 NOTE 104 This register the table in the open table list. so that it can be 105 found by future heap_open() calls. 106 */ 107 108 HP_INFO *heap_open(const char *name, int mode) 109 { 110 HP_INFO *info; 111 HP_SHARE *share; 112 DBUG_ENTER("heap_open"); 113 114 mysql_mutex_lock(&THR_LOCK_heap); 115 if (!(share= hp_find_named_heap(name))) 116 { 117 my_errno= ENOENT; 118 mysql_mutex_unlock(&THR_LOCK_heap); 119 DBUG_RETURN(0); 120 } 121 if ((info= heap_open_from_share(share, mode))) 122 { 123 info->open_list.data= (void*) info; 124 heap_open_list= list_add(heap_open_list,&info->open_list); 125 } 126 mysql_mutex_unlock(&THR_LOCK_heap); 127 DBUG_RETURN(info); 128 } 129 130 131 /* map name to a heap-nr. If name isn't found return 0 */ 132 133 HP_SHARE *hp_find_named_heap(const char *name) 134 { 135 LIST *pos; 136 HP_SHARE *info; 137 DBUG_ENTER("heap_find"); 138 DBUG_PRINT("enter",("name: %s",name)); 139 140 for (pos= heap_share_list; pos; pos= pos->next) 141 { 142 info= (HP_SHARE*) pos->data; 143 if (!strcmp(name, info->name)) 144 { 145 DBUG_PRINT("exit", ("Old heap_database: %p", info)); 146 DBUG_RETURN(info); 147 } 148 } 149 DBUG_RETURN((HP_SHARE *) 0); 150 } 151 152 153