1 /* Copyright (c) 2005, 2018, 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, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software Foundation,
21    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22 
23 #ifndef TABLE_MAPPING_H
24 #define TABLE_MAPPING_H
25 
26 #include "my_global.h"
27 #include "hash.h"        // HASH
28 
29 /* Forward declarations */
30 #ifndef MYSQL_CLIENT
31 struct TABLE;
32 #else
33 class Table_map_log_event;
34 typedef Table_map_log_event TABLE;
35 void free_table_map_log_event(TABLE *table);
36 #endif
37 
38 
39 /*
40   CLASS table_mapping
41 
42   RESPONSIBILITIES
43     The table mapping is used to map table id's to table pointers
44 
45   COLLABORATION
46     RELAY_LOG    For mapping table id:s to tables when receiving events.
47  */
48 
49 /*
50   Guilhem to Mats:
51   in the table_mapping class, the memory is allocated and never freed (until
52   destruction). So this is a good candidate for allocating inside a MEM_ROOT:
53   it gives the efficient allocation in chunks (like in expand()). So I have
54   introduced a MEM_ROOT.
55 
56   Note that inheriting from Sql_alloc had no effect: it has effects only when
57   "ptr= new table_mapping" is called, and this is never called. And it would
58   then allocate from thd->mem_root which is a highly volatile object (reset
59   from example after executing each query, see dispatch_command(), it has a
60   free_root() at end); as the table_mapping object is supposed to live longer
61   than a query, it was dangerous.
62   A dedicated MEM_ROOT needs to be used, see below.
63 */
64 
65 class table_mapping {
66 
67 private:
68   MEM_ROOT m_mem_root;
69 
70 public:
71 
72   enum enum_error {
73       ERR_NO_ERROR = 0,
74       ERR_LIMIT_EXCEEDED,
75       ERR_MEMORY_ALLOCATION
76   };
77 
78   table_mapping();
79   ~table_mapping();
80 
81   TABLE* get_table(ulonglong table_id);
82 
83   int       set_table(ulonglong table_id, TABLE* table);
84   int       remove_table(ulonglong table_id);
85   void      clear_tables();
count()86   ulong     count() const { return m_table_ids.records; }
87 
88 private:
89   /*
90     This is a POD (Plain Old Data).  Keep it that way (we apply offsetof() to
91     it, which only works for PODs)
92   */
93   struct entry {
94     ulonglong table_id;
95     union {
96       TABLE *table;
97       entry *next;
98     };
99   };
100 
find_entry(ulonglong table_id)101   entry *find_entry(ulonglong table_id)
102   {
103     return (entry *) my_hash_search(&m_table_ids,
104                                     (uchar*)&table_id,
105                                     sizeof(table_id));
106   }
107   int expand();
108 
109   /*
110     Head of the list of free entries; "free" in the sense that it's an
111     allocated entry free for use, NOT in the sense that it's freed
112     memory.
113   */
114   entry *m_free;
115 
116   /* Correspondance between an id (a number) and a TABLE object */
117   HASH m_table_ids;
118 };
119 
120 #endif
121