1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#ifndef TABLE_CACHE_H_INCLUDED
#define TABLE_CACHE_H_INCLUDED
/* Copyright (c) 2000, 2012, Oracle and/or its affiliates.
Copyright (c) 2010, 2011 Monty Program Ab
Copyright (C) 2013 Sergey Vojtovich and MariaDB Foundation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
struct Share_free_tables
{
typedef I_P_List <TABLE, TABLE_share> List;
List list;
/** Avoid false sharing between instances */
char pad[CPU_LEVEL1_DCACHE_LINESIZE];
};
typedef int64 tdc_version_t;
#define TDC_VERSION_MAX INT_MAX64
struct TDC_element
{
uchar m_key[NAME_LEN + 1 + NAME_LEN + 1];
uint m_key_length;
tdc_version_t version;
bool flushed;
TABLE_SHARE *share;
/**
Protects ref_count, m_flush_tickets, all_tables, flushed, all_tables_refs.
*/
mysql_mutex_t LOCK_table_share;
mysql_cond_t COND_release;
TDC_element *next, **prev; /* Link to unused shares */
uint ref_count; /* How many TABLE objects uses this */
uint all_tables_refs; /* Number of refs to all_tables */
/**
List of tickets representing threads waiting for the share to be flushed.
*/
Wait_for_flush_list m_flush_tickets;
/*
Doubly-linked (back-linked) lists of used and unused TABLE objects
for this share.
*/
All_share_tables_list all_tables;
/** Avoid false sharing between TDC_element and free_tables */
char pad[CPU_LEVEL1_DCACHE_LINESIZE];
Share_free_tables free_tables[1];
};
enum enum_tdc_remove_table_type
{
TDC_RT_REMOVE_ALL,
TDC_RT_REMOVE_NOT_OWN,
TDC_RT_REMOVE_UNUSED,
TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE
};
extern ulong tdc_size;
extern ulong tc_size;
extern uint32 tc_instances;
extern uint32 tc_active_instances;
extern bool tdc_init(void);
extern void tdc_start_shutdown(void);
extern void tdc_deinit(void);
extern ulong tdc_records(void);
extern void tdc_purge(bool all);
extern TDC_element *tdc_lock_share(THD *thd, const char *db,
const char *table_name);
extern void tdc_unlock_share(TDC_element *element);
extern TABLE_SHARE *tdc_acquire_share(THD *thd, TABLE_LIST *tl, uint flags,
TABLE **out_table= 0);
extern void tdc_release_share(TABLE_SHARE *share);
extern bool tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
const char *db, const char *table_name,
bool kill_delayed_threads);
extern int tdc_wait_for_old_version(THD *thd, const char *db,
const char *table_name,
ulong wait_timeout, uint deadlock_weight,
tdc_version_t refresh_version= TDC_VERSION_MAX);
extern tdc_version_t tdc_refresh_version(void);
extern tdc_version_t tdc_increment_refresh_version(void);
extern int tdc_iterate(THD *thd, my_hash_walk_action action, void *argument,
bool no_dups= false);
extern uint tc_records(void);
extern void tc_purge(bool mark_flushed= false);
extern void tc_add_table(THD *thd, TABLE *table);
extern void tc_release_table(TABLE *table);
extern TABLE *tc_acquire_table(THD *thd, TDC_element *element);
/**
Create a table cache key for non-temporary table.
@param key Buffer for key (must be at least NAME_LEN*2+2 bytes).
@param db Database name.
@param table_name Table name.
@return Length of key.
*/
inline uint tdc_create_key(char *key, const char *db, const char *table_name)
{
/*
In theory caller should ensure that both db and table_name are
not longer than NAME_LEN bytes. In practice we play safe to avoid
buffer overruns.
*/
return (uint) (strmake(strmake(key, db, NAME_LEN) + 1, table_name,
NAME_LEN) - key + 1);
}
#endif /* TABLE_CACHE_H_INCLUDED */
|