1 /*
2 Copyright (c) 2005, 2013, 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, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include "Rope.hpp"
26 #include "DataBuffer2.hpp"
27
28 #define JAM_FILE_ID 330
29
30
31 #define DEBUG_ROPE 0
32
33 void
copy(char * buf) const34 ConstRope::copy(char* buf) const {
35 char * ptr = buf;
36 if(DEBUG_ROPE)
37 ndbout_c("ConstRope::copy() head = [ %d 0x%x 0x%x ]",
38 head.used, head.firstItem, head.lastItem);
39 Uint32 left = head.used;
40 Ptr<Segment> curr;
41 curr.i = head.firstItem;
42 while(left > 4 * getSegmentSize()){
43 thePool.getPtr(curr);
44 memcpy(buf, curr.p->data, 4 * getSegmentSize());
45 curr.i = curr.p->nextPool;
46 left -= 4 * getSegmentSize();
47 buf += 4 * getSegmentSize();
48 }
49 if(left > 0){
50 thePool.getPtr(curr);
51 memcpy(buf, curr.p->data, left);
52 }
53
54 if(DEBUG_ROPE)
55 ndbout_c("ConstRope::copy()-> %s", ptr);
56 }
57
58 int
compare(const char * str,Uint32 len) const59 ConstRope::compare(const char * str, Uint32 len) const {
60 if(DEBUG_ROPE)
61 ndbout_c("ConstRope[ %d 0x%x 0x%x ]::compare(%s, %d)",
62 head.used, head.firstItem, head.lastItem, str, (int) len);
63 Uint32 left = head.used > len ? len : head.used;
64 Ptr<Segment> curr;
65 curr.i = head.firstItem;
66 while(left > 4 * getSegmentSize()){
67 thePool.getPtr(curr);
68 int res = memcmp(str, (const char*)curr.p->data, 4 * getSegmentSize());
69 if(res != 0){
70 if(DEBUG_ROPE)
71 ndbout_c("ConstRope::compare(%s, %d, %s) -> %d", str, left,
72 (const char*)curr.p->data, res);
73 return res;
74 }
75 curr.i = curr.p->nextPool;
76 left -= 4 * getSegmentSize();
77 str += 4 * getSegmentSize();
78 }
79
80 if(left > 0){
81 thePool.getPtr(curr);
82 int res = memcmp(str, (const char*)curr.p->data, left);
83 if(res){
84 if(DEBUG_ROPE)
85 ndbout_c("ConstRope::compare(%s, %d, %s) -> %d",
86 str, left, (const char*)curr.p->data, res);
87 return res;
88 }
89 }
90 if(DEBUG_ROPE)
91 ndbout_c("ConstRope::compare(%s, %d) -> %d", str, (int) len, head.used > len);
92 return head.used > len;
93 }
94
95 void
copy(char * buf) const96 LocalRope::copy(char* buf) const {
97 char * ptr = buf;
98 if(DEBUG_ROPE)
99 ndbout_c("LocalRope::copy() head = [ %d 0x%x 0x%x ]",
100 head.used, head.firstItem, head.lastItem);
101 Uint32 left = head.used;
102 Ptr<Segment> curr;
103 curr.i = head.firstItem;
104 while(left > 4 * getSegmentSize()){
105 thePool.getPtr(curr);
106 memcpy(buf, curr.p->data, 4 * getSegmentSize());
107 curr.i = curr.p->nextPool;
108 left -= 4 * getSegmentSize();
109 buf += 4 * getSegmentSize();
110 }
111 if(left > 0){
112 thePool.getPtr(curr);
113 memcpy(buf, curr.p->data, left);
114 }
115 if(DEBUG_ROPE)
116 ndbout_c("LocalRope::copy()-> %s", ptr);
117 }
118
119 int
compare(const char * str,Uint32 len) const120 LocalRope::compare(const char * str, Uint32 len) const {
121 if(DEBUG_ROPE)
122 ndbout_c("LocalRope::compare(%s, %d)", str, (int) len);
123 Uint32 left = head.used > len ? len : head.used;
124 Ptr<Segment> curr;
125 curr.i = head.firstItem;
126 while(left > 4 * getSegmentSize()){
127 thePool.getPtr(curr);
128 int res = memcmp(str, (const char*)curr.p->data, 4 * getSegmentSize());
129 if(res != 0){
130 if(DEBUG_ROPE)
131 ndbout_c("LocalRope::compare(%s, %d, %s) -> %d", str, (int) len,
132 (const char*)curr.p->data, res);
133 return res;
134 }
135
136 curr.i = curr.p->nextPool;
137 left -= 4 * getSegmentSize();
138 str += 4 * getSegmentSize();
139 }
140
141 if(left > 0){
142 thePool.getPtr(curr);
143 int res = memcmp(str, (const char*)curr.p->data, left);
144 if(res){
145 if(DEBUG_ROPE)
146 ndbout_c("LocalRope::compare(%s, %d) -> %d", str, (int) len, res);
147 return res;
148 }
149 }
150 if(DEBUG_ROPE)
151 ndbout_c("LocalRope::compare(%s, %d) -> %d", str, (int) len, head.used > len);
152 return head.used > len;
153 }
154
155 bool
assign(const char * s,Uint32 len,Uint32 hash)156 LocalRope::assign(const char * s, Uint32 len, Uint32 hash){
157 if(DEBUG_ROPE)
158 ndbout_c("LocalRope::assign(%s, %d, 0x%x)", s, (int) len, hash);
159 m_hash = hash;
160 head.used = (head.used + 3) / 4;
161 release();
162 if(append((const Uint32*)s, len >> 2)){
163 if(len & 3){
164 Uint32 buf = 0;
165 const char * src = (const char*)(((Uint32*)s)+(len >> 2));
166 char* dst = (char*)&buf;
167 Uint32 left = len & 3;
168 while(left){
169 * dst ++ = * src++;
170 left--;
171 }
172 if(!append(&buf, 1))
173 return false;
174 }
175 head.used = len;
176 if(DEBUG_ROPE)
177 ndbout_c("LocalRope::assign(...) head = [ %d 0x%x 0x%x ]",
178 head.used, head.firstItem, head.lastItem);
179 return true;
180 }
181 return false;
182 }
183
184 void
erase()185 LocalRope::erase(){
186 head.used = (head.used + 3) / 4;
187 release();
188 }
189
190 Uint32
hash(const char * p,Uint32 len)191 LocalRope::hash(const char * p, Uint32 len){
192 if(DEBUG_ROPE)
193 ndbout_c("LocalRope::hash(%s, %d)", p, len);
194 Uint32 h = 0;
195 for (; len > 0; len--)
196 h = (h << 5) + h + (* p++);
197 if(DEBUG_ROPE)
198 ndbout_c("LocalRope::hash(...) -> 0x%x", h);
199 return h;
200 }
201
202 bool
equal(const ConstRope & r2) const203 ConstRope::equal(const ConstRope& r2) const
204 {
205 if (head.used != r2.head.used)
206 return false;
207
208 if (src.m_hash != r2.src.m_hash)
209 return false;
210
211 Uint32 left = head.used;
212 Ptr<Segment> s1, s2;
213 s1.i = head.firstItem;
214 s2.i = r2.head.firstItem;
215 while(left > 4 * getSegmentSize())
216 {
217 thePool.getPtr(s1);
218 thePool.getPtr(s2);
219 int res = memcmp(s1.p->data, s2.p->data, 4 * getSegmentSize());
220 if(res != 0)
221 {
222 return false;
223 }
224 s1.i = s1.p->nextPool;
225 s2.i = s2.p->nextPool;
226 left -= 4 * getSegmentSize();
227 }
228
229 if(left > 0)
230 {
231 thePool.getPtr(s1);
232 thePool.getPtr(s2);
233 int res = memcmp(s1.p->data, s2.p->data, left);
234 if (res != 0)
235 {
236 return false;
237 }
238 }
239 return true;
240 }
241