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