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 
heap_open_from_share(HP_SHARE * share,int mode)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 
heap_open_from_share_and_register(HP_SHARE * share,int mode)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 */
heap_release_share(HP_SHARE * share,my_bool internal_table)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 
heap_open(const char * name,int mode)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 
hp_find_named_heap(const char * name)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