MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Undo_buffer.cpp
1 /*
2  Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU 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 02110-1301 USA
16 */
17 
18 #include "Undo_buffer.hpp"
19 #define DBTUP_C
20 #include "Dbtup.hpp"
21 
22 #if ZPAGE_STATE_POS != 0
23 #error "PROBLEM!"
24 #endif
25 
26 struct UndoPage
27 {
28  Uint32 m_words_used;
29  Uint32 m_ref_count;
30  Uint32 m_data[GLOBAL_PAGE_SIZE_WORDS-2];
31 
32  STATIC_CONST( DATA_WORDS = GLOBAL_PAGE_SIZE_WORDS-2 );
33 };
34 
35 #if defined VM_TRACE || defined ERROR_INSERT
36 #define SAFE_UB
37 #endif
38 
39 static
40 inline
41 UndoPage*
42 get_page(Ndbd_mem_manager* mm, Uint32 no)
43 {
44  return ((UndoPage*)mm->get_memroot()) + no;
45 }
46 
47 Undo_buffer::Undo_buffer(Ndbd_mem_manager* mm)
48 {
49  m_mm = mm;
50  m_first_free = RNIL;
51  assert(sizeof(UndoPage) == 4*GLOBAL_PAGE_SIZE_WORDS);
52 }
53 
54 Uint32 *
56 {
57  UndoPage* page;
58  assert(words);
59 #ifdef SAFE_UB
60  words += 2; // header + footer
61 #endif
62  if (m_first_free == RNIL)
63  {
64  page= (UndoPage*)m_mm->alloc_page(RG_DATAMEM,
65  &m_first_free,
66  Ndbd_mem_manager::NDB_ZONE_ANY);
67  if(page == 0)
68  return 0;
69  page->m_words_used= 0;
70  page->m_ref_count= 0;
71  }
72 
73  page = get_page(m_mm, m_first_free);
74  Uint32 pos= page->m_words_used;
75 
76  if (words + pos > UndoPage::DATA_WORDS)
77  {
78  m_first_free= RNIL;
79  return alloc_copy_tuple(dst, words);
80  }
81 
82  dst->m_page_no = m_first_free;
83  dst->m_page_idx = pos;
84 
85  page->m_ref_count++;
86  page->m_words_used = pos + words;
87 #ifdef SAFE_UB
88  page->m_data[pos] = words; // header
89  page->m_data[pos + words - 1] = m_first_free + pos;
90  pos ++;
91 #endif
92  return page->m_data + pos;
93 }
94 
95 void
97 {
98  assert(key->m_page_no == m_first_free);
99  UndoPage* page= get_page(m_mm, key->m_page_no);
100  assert(page->m_words_used >= words);
101  page->m_words_used -= words;
102 }
103 
104 void
106 {
107  UndoPage* page= get_page(m_mm, key->m_page_no);
108  Uint32 cnt= page->m_ref_count;
109  assert(cnt);
110 
111  page->m_ref_count= cnt - 1;
112 
113  if (cnt - 1 == 0)
114  {
115  page->m_words_used= 0;
116  if (m_first_free == key->m_page_no)
117  {
118  //ndbout_c("resetting page");
119  }
120  else
121  {
122  //ndbout_c("returning page");
123  m_mm->release_page(RG_DATAMEM, key->m_page_no);
124  }
125  }
126  key->setNull();
127 }
128 
129 Uint32 *
131 {
132  UndoPage* page = get_page(m_mm, key->m_page_no);
133  Uint32 * ptr = page->m_data + key->m_page_idx;
134 #ifdef SAFE_UB
135  Uint32 words = * ptr;
136  Uint32 check = ptr[words - 1];
137  if (unlikely(! ((check == key->m_page_no + key->m_page_idx))))
138  {
139  abort();
140  }
141  ptr++;
142 #endif
143  return ptr;
144 }