1// trseize.cpp -- Regression test program, resizing tests 2// $Id: tresize.cpp 1230 2007-03-09 15:58:53Z jcw $ 3// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html 4 5#include "regress.h" 6 7#include <stdlib.h> // strtol 8#include <string.h> // memory functions 9 10class CResizer: public c4_Storage { 11 public: 12 CResizer(const char *file); 13 ~CResizer(); 14 15 void Verify(); 16 17 int Ins(int, int); 18 int Del(int, int); 19 20 private: 21 enum { 22 kMaxData = 15000 23 }; 24 char *_refData; 25 int _refSize; 26 27 c4_View _attached; 28 c4_View _unattached; 29 c4_IntProp _prop; 30 31 char _seed; 32 33 CResizer(const CResizer &); // not implemented 34 void operator = (const CResizer &); // not implemented 35}; 36 37CResizer::CResizer(const char *file): c4_Storage(file, 1), _refSize(0), _prop( 38 "p1"), _seed(0) { 39 SetStructure("a[p1:I]"); 40 41 _refData = new char[kMaxData]; 42 43 _attached = View("a"); 44 45 Verify(); 46} 47 48CResizer::~CResizer() { 49 Verify(); 50 51 Commit(); 52 53 Verify(); 54 55 delete [] _refData; 56} 57 58void CResizer::Verify() { 59 int i; 60 61 A(_refSize == _unattached.GetSize()); 62 A(_refSize == _attached.GetSize()); 63 64 for (i = 0; i < _refSize; ++i) { 65 A(_refData[i] == _prop(_unattached[i])); 66 A(_refData[i] == _prop(_attached[i])); 67 } 68} 69 70int CResizer::Ins(int pos_, int cnt_) { 71 A(pos_ <= _refSize); 72 A(_refSize + cnt_ < kMaxData); 73 74 memmove(_refData + pos_ + cnt_, _refData + pos_, _refSize - pos_); 75 _refSize += cnt_; 76 77 c4_Row row; 78 _unattached.InsertAt(pos_, row, cnt_); 79 _attached.InsertAt(pos_, row, cnt_); 80 81 for (int i = pos_; i < pos_ + cnt_; ++i) { 82 _refData[i] = ++_seed; 83 _prop(_unattached[i]) = _seed; 84 _prop(_attached[i]) = _seed; 85 86 if (_seed >= 123) 87 _seed = 0; 88 } 89 90 Verify(); 91 92 return _refSize; 93} 94 95int CResizer::Del(int pos_, int cnt_) { 96 A(pos_ + cnt_ <= _refSize); 97 98 _refSize -= cnt_; 99 memmove(_refData + pos_, _refData + pos_ + cnt_, _refSize - pos_); 100 101 _unattached.RemoveAt(pos_, cnt_); 102 _attached.RemoveAt(pos_, cnt_); 103 104 Verify(); 105 106 return _refSize; 107} 108 109void TestResize() { 110 B(r00, Simple insert, 0)W(r00a); 111 { 112 CResizer r1("r00a"); 113 114 int n = r1.Ins(0, 250); 115 A(n == 250); 116 117 } 118 D(r00a); 119 R(r00a); 120 E; 121 122 B(r01, Simple removes, 0)W(r01a); 123 { 124 CResizer r1("r01a"); 125 int n; 126 127 n = r1.Ins(0, 500); 128 A(n == 500); 129 130 n = r1.Del(0, 50); 131 A(n == 450); 132 n = r1.Del(350, 100); 133 A(n == 350); 134 n = r1.Del(25, 150); 135 A(n == 200); 136 n = r1.Del(0, 200); 137 A(n == 0); 138 139 n = r1.Ins(0, 15); 140 A(n == 15); 141 142 } 143 D(r01a); 144 R(r01a); 145 E; 146 147 B(r02, Large inserts and removes, 0)W(r02a); 148 { 149 int big = sizeof(int) == sizeof(short) ? 1000 : 4000; 150 151 CResizer r1("r02a"); 152 int n; 153 154 n = r1.Ins(0, 2000); 155 A(n == 2000); 156 n = r1.Ins(0, 3000); 157 A(n == 5000); 158 n = r1.Ins(5000, 1000+big); 159 A(n == 6000+big); 160 n = r1.Ins(100, 10); 161 A(n == 6010+big); 162 n = r1.Ins(4000, 100); 163 A(n == 6110+big); 164 n = r1.Ins(0, 1001); 165 A(n == 7111+big); 166 167 n = r1.Del(7111, big); 168 A(n == 7111); 169 n = r1.Del(0, 4111); 170 A(n == 3000); 171 n = r1.Del(10, 10); 172 A(n == 2990); 173 n = r1.Del(10, 10); 174 A(n == 2980); 175 n = r1.Del(5, 10); 176 A(n == 2970); 177 n = r1.Del(0, 990); 178 A(n == 1980); 179 n = r1.Del(3, 1975); 180 A(n == 5); 181 182 } 183 D(r02a); 184 R(r02a); 185 E; 186 187 B(r03, Binary property insertions, 0)W(r03a); 188 { 189 c4_BytesProp p1("p1"); 190 c4_Storage s1("r03a", 1); 191 s1.SetStructure("a[p1:B]"); 192 c4_View v1 = s1.View("a"); 193 194 char buf[1024]; 195 196 memset(buf, 0x11, sizeof buf); 197 v1.Add(p1[c4_Bytes(buf, sizeof buf)]); 198 199 memset(buf, 0x22, sizeof buf); 200 v1.Add(p1[c4_Bytes(buf, sizeof buf / 2)]); 201 202 s1.Commit(); 203 204 memset(buf, 0x33, sizeof buf); 205 p1(v1[1]) = c4_Bytes(buf, sizeof buf); // fix c4_Column::CopyData 206 207 memset(buf, 0x44, sizeof buf); 208 v1.Add(p1[c4_Bytes(buf, sizeof buf / 3)]); 209 210 s1.Commit(); 211 212 memset(buf, 0x55, sizeof buf); 213 v1.InsertAt(1, p1[c4_Bytes(buf, sizeof buf)]); 214 215 memset(buf, 0x66, sizeof buf); 216 v1.InsertAt(1, p1[c4_Bytes(buf, sizeof buf / 4)]); 217 218 s1.Commit(); 219 220 } 221 D(r03a); 222 R(r03a); 223 E; 224 225 B(r04, Scripted string property tests, 0)W(r04a); 226 { 227 c4_StringProp p1("p1"); 228 c4_Storage s1("r04a", 1); 229 s1.SetStructure("a[p1:S]"); 230 231 // This code implements a tiny language to specify tests in: 232 // 233 // "<X>,<Y>A" add X partial buffers of size Y 234 // "<X>a" add X full buffers at end 235 // "<X>,<Y>C" change entry X to a partial buffer of size Y 236 // "<X>c" change entry at position X to a full buffer 237 // "<X>,<Y>I" insert partial buffer of size Y at position X 238 // "<X>i" insert a full buffer at position X 239 // "<X>,<Y>R" remove Y entries at position X 240 // "<X>r" remove one entry at position X 241 // 242 // ">" commit changes 243 // "<" rollback changes 244 // 245 // " " ignore spaces 246 // "<X>," for additional args 247 // "<X>=" verify number of rows is X 248 249 const char *scripts[] = { 250 // A B C D E F G H I J 251 "5a 5a 5a 1r 5r 10r 6r 2r > 10=", 252 "5a 5a 5a 1,200C 5,200C 10,200C 6,200C 2,200C > 15=", 253 "5a 5a 5a 1,300C 5,300C 10,300C 6,300C 2,300C > 15=", 254 255 // A B C D E F G H I J 256 "50a 50a 50a 10r 50r 100r 60r 20r > 145=", 257 "50a 50a 50a 10,200C 50,200C 100,200C 60,200C 20,200C > 150=", 258 "50a 50a 50a 10,300C 50,300C 100,300C 60,300C 20,300C > 150=", 259 260 // A B C D E F G H I J 261 "50,0A 50,0A 50,0A 10c 50c 100c 60c 20c > 150=", // asserts in 1.7b1 262 263 // A B C D E 264 "3,3A 1,10C 1,1C > 3=", // asserts in 1.7 - June 6 build 265 266 "", 0 267 }; 268 269 for (int i = 0; scripts[i]; ++i) { 270 c4_View v1 = s1.View("a"); 271 v1.RemoveAll(); 272 s1.Commit(); 273 A(v1.GetSize() == 0); // start with a clean slate each time 274 275 const char *p = scripts[i]; 276 277 char fill = '@'; 278 int save = 0; 279 c4_Row row; 280 281 while (*p) { 282 // default is a string of 255 chars (with additional null byte) 283 p1(row) = c4_String(++fill, 255); 284 285 int arg = (int)strtol(p, (char **) &p, 10); // loses const 286 287 switch (*p++) { 288 case 'A': 289 p1(row) = c4_String(fill, arg); 290 arg = save; 291 case 'a': 292 while (--arg >= 0) 293 v1.Add(row); 294 break; 295 case 'C': 296 p1(row) = c4_String(fill, arg); 297 arg = save; 298 case 'c': 299 v1.SetAt(arg, row); 300 break; 301 case 'I': 302 p1(row) = c4_String(fill, arg); 303 arg = save; 304 case 'i': 305 v1.InsertAt(arg, row); 306 break; 307 case 'R': 308 v1.RemoveAt(save, arg); 309 break; 310 case 'r': 311 v1.RemoveAt(arg); 312 break; 313 case '>': 314 s1.Commit(); 315 break; 316 case '<': 317 s1.Rollback(); 318 v1 = s1.View("a"); 319 break; 320 case ' ': 321 break; 322 case ',': 323 save = arg; 324 break; 325 case '=': 326 A(v1.GetSize() == arg); 327 break; 328 } 329 } 330 } 331 332 s1.Commit(); 333 334 } 335 D(r04a); 336 R(r04a); 337 E; 338} 339