1 /* Copyright (c) 2005, 2010, 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 #ifndef TABLE_MAPPING_H
17 #define TABLE_MAPPING_H
18 
19 /* Forward declarations */
20 #ifndef MYSQL_CLIENT
21 struct TABLE;
22 #else
23 class Table_map_log_event;
24 typedef Table_map_log_event TABLE;
25 void free_table_map_log_event(TABLE *table);
26 #endif
27 
28 
29 /*
30   CLASS table_mapping
31 
32   RESPONSIBILITIES
33     The table mapping is used to map table id's to table pointers
34 
35   COLLABORATION
36     RELAY_LOG    For mapping table id:s to tables when receiving events.
37  */
38 
39 /*
40   Guilhem to Mats:
41   in the table_mapping class, the memory is allocated and never freed (until
42   destruction). So this is a good candidate for allocating inside a MEM_ROOT:
43   it gives the efficient allocation in chunks (like in expand()). So I have
44   introduced a MEM_ROOT.
45 
46   Note that inheriting from Sql_alloc had no effect: it has effects only when
47   "ptr= new table_mapping" is called, and this is never called. And it would
48   then allocate from thd->mem_root which is a highly volatile object (reset
49   from example after executing each query, see dispatch_command(), it has a
50   free_root() at end); as the table_mapping object is supposed to live longer
51   than a query, it was dangerous.
52   A dedicated MEM_ROOT needs to be used, see below.
53 */
54 
55 #include "hash.h"                               /* HASH */
56 
57 class table_mapping {
58 
59 private:
60   MEM_ROOT m_mem_root;
61 
62 public:
63 
64   enum enum_error {
65       ERR_NO_ERROR = 0,
66       ERR_LIMIT_EXCEEDED,
67       ERR_MEMORY_ALLOCATION
68   };
69 
70   table_mapping();
71   ~table_mapping();
72 
73   TABLE* get_table(ulonglong table_id);
74 
75   int       set_table(ulonglong table_id, TABLE* table);
76   int       remove_table(ulonglong table_id);
77   void      clear_tables();
count()78   ulong     count() const { return m_table_ids.records; }
79 
80 private:
81   /*
82     This is a POD (Plain Old Data).  Keep it that way (we apply offsetof() to
83     it, which only works for PODs)
84   */
85   struct entry {
86     ulonglong table_id;
87     union {
88       TABLE *table;
89       entry *next;
90     };
91   };
92 
find_entry(ulonglong table_id)93   entry *find_entry(ulonglong table_id)
94   {
95     return (entry *) my_hash_search(&m_table_ids,
96                                     (uchar*)&table_id,
97                                     sizeof(table_id));
98   }
99   int expand();
100 
101   /*
102     Head of the list of free entries; "free" in the sense that it's an
103     allocated entry free for use, NOT in the sense that it's freed
104     memory.
105   */
106   entry *m_free;
107 
108   /* Correspondance between an id (a number) and a TABLE object */
109   HASH m_table_ids;
110 };
111 
112 #endif
113