MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Rope.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 "Rope.hpp"
19 #include "DataBuffer2.hpp"
20 
21 #define DEBUG_ROPE 0
22 
23 void
24 ConstRope::copy(char* buf) const {
25  char * ptr = buf;
26  if(DEBUG_ROPE)
27  ndbout_c("ConstRope::copy() head = [ %d 0x%x 0x%x ]",
28  head.used, head.firstItem, head.lastItem);
29  Uint32 left = head.used;
30  Ptr<Segment> curr;
31  curr.i = head.firstItem;
32  while(left > 4 * getSegmentSize()){
33  thePool.getPtr(curr);
34  memcpy(buf, curr.p->data, 4 * getSegmentSize());
35  curr.i = curr.p->nextPool;
36  left -= 4 * getSegmentSize();
37  buf += 4 * getSegmentSize();
38  }
39  if(left > 0){
40  thePool.getPtr(curr);
41  memcpy(buf, curr.p->data, left);
42  }
43 
44  if(DEBUG_ROPE)
45  ndbout_c("ConstRope::copy()-> %s", ptr);
46 }
47 
48 int
49 ConstRope::compare(const char * str, Uint32 len) const {
50  if(DEBUG_ROPE)
51  ndbout_c("ConstRope[ %d 0x%x 0x%x ]::compare(%s, %d)",
52  head.used, head.firstItem, head.lastItem, str, (int) len);
53  Uint32 left = head.used > len ? len : head.used;
54  Ptr<Segment> curr;
55  curr.i = head.firstItem;
56  while(left > 4 * getSegmentSize()){
57  thePool.getPtr(curr);
58  int res = memcmp(str, (const char*)curr.p->data, 4 * getSegmentSize());
59  if(res != 0){
60  if(DEBUG_ROPE)
61  ndbout_c("ConstRope::compare(%s, %d, %s) -> %d", str, left,
62  (const char*)curr.p->data, res);
63  return res;
64  }
65  curr.i = curr.p->nextPool;
66  left -= 4 * getSegmentSize();
67  str += 4 * getSegmentSize();
68  }
69 
70  if(left > 0){
71  thePool.getPtr(curr);
72  int res = memcmp(str, (const char*)curr.p->data, left);
73  if(res){
74  if(DEBUG_ROPE)
75  ndbout_c("ConstRope::compare(%s, %d, %s) -> %d",
76  str, left, (const char*)curr.p->data, res);
77  return res;
78  }
79  }
80  if(DEBUG_ROPE)
81  ndbout_c("ConstRope::compare(%s, %d) -> %d", str, (int) len, head.used > len);
82  return head.used > len;
83 }
84 
85 void
86 Rope::copy(char* buf) const {
87  char * ptr = buf;
88  if(DEBUG_ROPE)
89  ndbout_c("Rope::copy() head = [ %d 0x%x 0x%x ]",
90  head.used, head.firstItem, head.lastItem);
91  Uint32 left = head.used;
92  Ptr<Segment> curr;
93  curr.i = head.firstItem;
94  while(left > 4 * getSegmentSize()){
95  thePool.getPtr(curr);
96  memcpy(buf, curr.p->data, 4 * getSegmentSize());
97  curr.i = curr.p->nextPool;
98  left -= 4 * getSegmentSize();
99  buf += 4 * getSegmentSize();
100  }
101  if(left > 0){
102  thePool.getPtr(curr);
103  memcpy(buf, curr.p->data, left);
104  }
105  if(DEBUG_ROPE)
106  ndbout_c("Rope::copy()-> %s", ptr);
107 }
108 
109 int
110 Rope::compare(const char * str, Uint32 len) const {
111  if(DEBUG_ROPE)
112  ndbout_c("Rope::compare(%s, %d)", str, (int) len);
113  Uint32 left = head.used > len ? len : head.used;
114  Ptr<Segment> curr;
115  curr.i = head.firstItem;
116  while(left > 4 * getSegmentSize()){
117  thePool.getPtr(curr);
118  int res = memcmp(str, (const char*)curr.p->data, 4 * getSegmentSize());
119  if(res != 0){
120  if(DEBUG_ROPE)
121  ndbout_c("Rope::compare(%s, %d, %s) -> %d", str, (int) len,
122  (const char*)curr.p->data, res);
123  return res;
124  }
125 
126  curr.i = curr.p->nextPool;
127  left -= 4 * getSegmentSize();
128  str += 4 * getSegmentSize();
129  }
130 
131  if(left > 0){
132  thePool.getPtr(curr);
133  int res = memcmp(str, (const char*)curr.p->data, left);
134  if(res){
135  if(DEBUG_ROPE)
136  ndbout_c("Rope::compare(%s, %d) -> %d", str, (int) len, res);
137  return res;
138  }
139  }
140  if(DEBUG_ROPE)
141  ndbout_c("Rope::compare(%s, %d) -> %d", str, (int) len, head.used > len);
142  return head.used > len;
143 }
144 
145 bool
146 Rope::assign(const char * s, Uint32 len, Uint32 hash){
147  if(DEBUG_ROPE)
148  ndbout_c("Rope::assign(%s, %d, 0x%x)", s, (int) len, hash);
149  m_hash = hash;
150  head.used = (head.used + 3) / 4;
151  release();
152  if(append((const Uint32*)s, len >> 2)){
153  if(len & 3){
154  Uint32 buf = 0;
155  const char * src = (const char*)(((Uint32*)s)+(len >> 2));
156  char* dst = (char*)&buf;
157  Uint32 left = len & 3;
158  while(left){
159  * dst ++ = * src++;
160  left--;
161  }
162  if(!append(&buf, 1))
163  return false;
164  }
165  head.used = len;
166  if(DEBUG_ROPE)
167  ndbout_c("Rope::assign(...) head = [ %d 0x%x 0x%x ]",
168  head.used, head.firstItem, head.lastItem);
169  return true;
170  }
171  return false;
172 }
173 
174 void
175 Rope::erase(){
176  head.used = (head.used + 3) / 4;
177  release();
178 }
179 
180 Uint32
181 Rope::hash(const char * p, Uint32 len){
182  if(DEBUG_ROPE)
183  ndbout_c("Rope::hash(%s, %d)", p, len);
184  Uint32 h = 0;
185  for (; len > 0; len--)
186  h = (h << 5) + h + (* p++);
187  if(DEBUG_ROPE)
188  ndbout_c("Rope::hash(...) -> 0x%x", h);
189  return h;
190 }
191 
192 bool
193 ConstRope::equal(const ConstRope& r2) const
194 {
195  if (head.used != r2.head.used)
196  return false;
197 
198  if (src.m_hash != r2.src.m_hash)
199  return false;
200 
201  Uint32 left = head.used;
202  Ptr<Segment> s1, s2;
203  s1.i = head.firstItem;
204  s2.i = r2.head.firstItem;
205  while(left > 4 * getSegmentSize())
206  {
207  thePool.getPtr(s1);
208  thePool.getPtr(s2);
209  int res = memcmp(s1.p->data, s2.p->data, 4 * getSegmentSize());
210  if(res != 0)
211  {
212  return false;
213  }
214  s1.i = s1.p->nextPool;
215  s2.i = s2.p->nextPool;
216  left -= 4 * getSegmentSize();
217  }
218 
219  if(left > 0)
220  {
221  thePool.getPtr(s1);
222  thePool.getPtr(s2);
223  int res = memcmp(s1.p->data, s2.p->data, left);
224  if (res != 0)
225  {
226  return false;
227  }
228  }
229  return true;
230 }