~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to sql/rpl_gtid_sid_map.cc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2011, 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 "hash.h"
 
21
#include "mysqld_error.h"
 
22
 
 
23
 
 
24
Sid_map::Sid_map(Checkable_rwlock *_sid_lock)
 
25
  : sid_lock(_sid_lock)
 
26
{
 
27
  DBUG_ENTER("Sid_map::Sid_map");
 
28
  my_init_dynamic_array(&_sidno_to_sid, sizeof(Node *), 8, 8);
 
29
  my_init_dynamic_array(&_sorted, sizeof(rpl_sidno), 8, 8);
 
30
  my_hash_init(&_sid_to_sidno, &my_charset_bin, 20,
 
31
               offsetof(Node, sid.bytes), Uuid::BYTE_LENGTH, NULL,
 
32
               my_free, 0);
 
33
  DBUG_VOID_RETURN;
 
34
}
 
35
 
 
36
 
 
37
Sid_map::~Sid_map()
 
38
{
 
39
  DBUG_ENTER("Sid_map::~Sid_map");
 
40
  delete_dynamic(&_sidno_to_sid);
 
41
  delete_dynamic(&_sorted);
 
42
  my_hash_free(&_sid_to_sidno);
 
43
  DBUG_VOID_RETURN;
 
44
}
 
45
 
 
46
 
 
47
/*
 
48
  This code is not being used but we will keep it as it may be
 
49
  useful to optimize gtids by avoiding sharing mappings from
 
50
  sid to sidno. For instance, the IO Thread and the SQL Thread
 
51
  may have different mappings in the future.
 
52
*/
 
53
#ifdef NON_DISABLED_GTID
 
54
enum_return_status Sid_map::clear()
 
55
{
 
56
  DBUG_ENTER("Sid_map::clear");
 
57
  my_hash_free(&_sid_to_sidno);
 
58
  my_hash_init(&_sid_to_sidno, &my_charset_bin, 20,
 
59
               offsetof(Node, sid.bytes), Uuid::BYTE_LENGTH, NULL,
 
60
               my_free, 0);
 
61
  reset_dynamic(&_sidno_to_sid);
 
62
  reset_dynamic(&_sorted);
 
63
  RETURN_OK;
 
64
}
 
65
#endif
 
66
 
 
67
 
 
68
rpl_sidno Sid_map::add_sid(const rpl_sid &sid)
 
69
{
 
70
  DBUG_ENTER("Sid_map::add_sid(const rpl_sid *)");
 
71
#ifndef DBUG_OFF
 
72
  char buf[Uuid::TEXT_LENGTH + 1];
 
73
  sid.to_string(buf);
 
74
  DBUG_PRINT("info", ("SID=%s", buf));
 
75
#endif
 
76
  if (sid_lock)
 
77
    sid_lock->assert_some_lock();
 
78
  Node *node= (Node *)my_hash_search(&_sid_to_sidno, sid.bytes,
 
79
                                     rpl_sid::BYTE_LENGTH);
 
80
  if (node != NULL)
 
81
  {
 
82
    DBUG_PRINT("info", ("existed as sidno=%d", node->sidno));
 
83
    DBUG_RETURN(node->sidno);
 
84
  }
 
85
 
 
86
  bool is_wrlock= false;
 
87
  if (sid_lock)
 
88
  {
 
89
    is_wrlock= sid_lock->is_wrlock();
 
90
    if (!is_wrlock)
 
91
    {
 
92
      sid_lock->unlock();
 
93
      sid_lock->wrlock();
 
94
    }
 
95
  }
 
96
  DBUG_PRINT("info", ("is_wrlock=%d sid_lock=%p", is_wrlock, sid_lock));
 
97
  rpl_sidno sidno;
 
98
  node= (Node *)my_hash_search(&_sid_to_sidno, sid.bytes,
 
99
                               rpl_sid::BYTE_LENGTH);
 
100
  if (node != NULL)
 
101
    sidno= node->sidno;
 
102
  else
 
103
  {
 
104
    sidno= get_max_sidno() + 1;
 
105
    if (add_node(sidno, sid) != RETURN_STATUS_OK)
 
106
      sidno= -1;
 
107
  }
 
108
 
 
109
  if (sid_lock)
 
110
  {
 
111
    if (!is_wrlock)
 
112
    {
 
113
      sid_lock->unlock();
 
114
      sid_lock->rdlock();
 
115
    }
 
116
  }
 
117
  DBUG_RETURN(sidno);
 
118
}
 
119
 
 
120
enum_return_status Sid_map::add_node(rpl_sidno sidno, const rpl_sid &sid)
 
121
{
 
122
  DBUG_ENTER("Sid_map::add_node(rpl_sidno, const rpl_sid *)");
 
123
  if (sid_lock)
 
124
    sid_lock->assert_some_wrlock();
 
125
  Node *node= (Node *)my_malloc(sizeof(Node), MYF(MY_WME));
 
126
  if (node == NULL)
 
127
    RETURN_REPORTED_ERROR;
 
128
 
 
129
  node->sidno= sidno;
 
130
  node->sid= sid;
 
131
  if (insert_dynamic(&_sidno_to_sid, &node) == 0)
 
132
  {
 
133
    if (insert_dynamic(&_sorted, &sidno) == 0)
 
134
    {
 
135
      if (my_hash_insert(&_sid_to_sidno, (uchar *)node) == 0)
 
136
      {
 
137
#ifdef MYSQL_SERVER
 
138
        /*
 
139
          If this is the global_sid_map, we take the opportunity to
 
140
          resize all arrays in gtid_state while holding the wrlock.
 
141
        */
 
142
        if (this != global_sid_map ||
 
143
            gtid_state->ensure_sidno() == RETURN_STATUS_OK)
 
144
#endif
 
145
        {
 
146
          // We have added one element to the end of _sorted.  Now we
 
147
          // bubble it down to the sorted position.
 
148
          int sorted_i= sidno - 1;
 
149
          rpl_sidno *prev_sorted_p= dynamic_element(&_sorted, sorted_i,
 
150
                                                    rpl_sidno *);
 
151
          sorted_i--;
 
152
          while (sorted_i >= 0)
 
153
          {
 
154
            rpl_sidno *sorted_p= dynamic_element(&_sorted, sorted_i,
 
155
                                                 rpl_sidno *);
 
156
            const rpl_sid &other_sid= sidno_to_sid(*sorted_p);
 
157
            if (memcmp(sid.bytes, other_sid.bytes,
 
158
                       rpl_sid::BYTE_LENGTH) >= 0)
 
159
              break;
 
160
            memcpy(prev_sorted_p, sorted_p, sizeof(rpl_sidno));
 
161
            sorted_i--;
 
162
            prev_sorted_p= sorted_p;
 
163
          }
 
164
          memcpy(prev_sorted_p, &sidno, sizeof(rpl_sidno));
 
165
          RETURN_OK;
 
166
        }
 
167
      }
 
168
      pop_dynamic(&_sorted);
 
169
    }
 
170
    pop_dynamic(&_sidno_to_sid);
 
171
  }
 
172
  my_free(node);
 
173
 
 
174
  BINLOG_ERROR(("Out of memory."), (ER_OUT_OF_RESOURCES, MYF(0)));
 
175
  RETURN_REPORTED_ERROR;
 
176
}