MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rpl_gtid_owned.cc
1 /* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or
4  modify it under the terms of the GNU General Public License as
5  published by the Free Software Foundation; version 2 of the
6  License.
7 
8  This program is distributed in the hope that it will be useful, but
9  WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
16  02110-1301 USA */
17 
18 #include "rpl_gtid.h"
19 
20 #include "mysqld_error.h"
21 #include "hash.h"
22 
23 
25  : sid_lock(_sid_lock)
26 {
27  my_init_dynamic_array(&sidno_to_hash, sizeof(HASH *), 0, 8);
28  /*
29  my_hash_init(&gtid_to_owner, &my_charset_bin, 20,
30  offsetof(Node, group), sizeof(Group), NULL,
31  my_free, 0);
32  */
33 }
34 
35 
37 {
38  // destructor should only be called when no other thread may access object
39  //sid_lock->assert_no_lock();
40  // need to hold lock before calling get_max_sidno
41  sid_lock->rdlock();
42  rpl_sidno max_sidno= get_max_sidno();
43  for (int sidno= 1; sidno <= max_sidno; sidno++)
44  {
45  HASH *hash= get_hash(sidno);
46  my_hash_free(hash);
47  my_free(hash);
48  }
49  delete_dynamic(&sidno_to_hash);
50  sid_lock->unlock();
51  //sid_lock->assert_no_lock();
52 }
53 
54 
55 enum_return_status Owned_gtids::ensure_sidno(rpl_sidno sidno)
56 {
57  DBUG_ENTER("Owned_gtids::ensure_sidno");
58  sid_lock->assert_some_wrlock();
59  rpl_sidno max_sidno= get_max_sidno();
60  if (sidno > max_sidno || get_hash(sidno) == NULL)
61  {
62  if (allocate_dynamic(&sidno_to_hash, sidno))
63  goto error;
64  for (int i= max_sidno; i < sidno; i++)
65  {
66  HASH *hash= (HASH *)my_malloc(sizeof(HASH), MYF(MY_WME));
67  if (hash == NULL)
68  goto error;
69  my_hash_init(hash, &my_charset_bin, 20,
70  offsetof(Node, gno), sizeof(rpl_gno), NULL,
71  my_free, 0);
72  set_dynamic(&sidno_to_hash, &hash, i);
73  }
74  }
75  RETURN_OK;
76 error:
77  BINLOG_ERROR(("Out of memory."), (ER_OUT_OF_RESOURCES, MYF(0)));
78  RETURN_REPORTED_ERROR;
79 }
80 
81 
82 enum_return_status Owned_gtids::add_gtid_owner(const Gtid &gtid,
83  my_thread_id owner)
84 {
85  DBUG_ENTER("Owned_gtids::add_gtid_owner(Gtid, my_thread_id)");
86  DBUG_ASSERT(!contains_gtid(gtid));
87  DBUG_ASSERT(gtid.sidno <= get_max_sidno());
88  Node *n= (Node *)my_malloc(sizeof(Node), MYF(MY_WME));
89  if (n == NULL)
90  RETURN_REPORTED_ERROR;
91  n->gno= gtid.gno;
92  n->owner= owner;
93  /*
94  printf("Owned_gtids(%p)::add sidno=%d gno=%lld n=%p n->owner=%u\n",
95  this, sidno, gno, n, n?n->owner:0);
96  */
97  if (my_hash_insert(get_hash(gtid.sidno), (const uchar *)n) != 0)
98  {
99  my_free(n);
100  BINLOG_ERROR(("Out of memory."), (ER_OUT_OF_RESOURCES, MYF(0)));
101  RETURN_REPORTED_ERROR;
102  }
103  RETURN_OK;
104 }
105 
106 
108 {
109  DBUG_ENTER("Owned_gtids::remove_gtid(Gtid)");
110  //printf("Owned_gtids::remove(sidno=%d gno=%lld)\n", sidno, gno);
111  //DBUG_ASSERT(contains_gtid(sidno, gno)); // allow group not owned
112  HASH *hash= get_hash(gtid.sidno);
113  DBUG_ASSERT(hash != NULL);
114  Node *node= get_node(hash, gtid.gno);
115  if (node != NULL)
116  {
117 #ifdef DBUG_OFF
118  my_hash_delete(hash, (uchar *)node);
119 #else
120  // my_hash_delete returns nonzero if the element does not exist
121  DBUG_ASSERT(my_hash_delete(hash, (uchar *)node) == 0);
122 #endif
123  }
124  DBUG_VOID_RETURN;
125 }
126 
127 
128 my_thread_id Owned_gtids::get_owner(const Gtid &gtid) const
129 {
130  Node *n= get_node(gtid);
131  if (n != NULL)
132  return n->owner;
133  return 0;
134 }
135 
136 
138 {
139  DBUG_ENTER("Owned_gtids::is_intersection_nonempty(Gtid_set *)");
140  if (sid_lock != NULL)
141  sid_lock->assert_some_wrlock();
142  Gtid_iterator git(this);
143  Gtid g= git.get();
144  while (g.sidno != 0)
145  {
146  if (other->contains_gtid(g.sidno, g.gno))
147  DBUG_RETURN(true);
148  git.next();
149  g= git.get();
150  }
151  DBUG_RETURN(false);
152 }