You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
6.9 KiB
290 lines
6.9 KiB
// trseize.cpp -- Regression test program, resizing tests
|
|
// $Id$
|
|
// This is part of Metakit, see http://www.equi4.com/metakit/
|
|
|
|
#include "regress.h"
|
|
|
|
#include <stdlib.h> // strtol
|
|
#include <string.h> // memory functions
|
|
|
|
class CResizer : public c4_Storage
|
|
{
|
|
public:
|
|
CResizer (const char* file);
|
|
~CResizer ();
|
|
|
|
void Verify();
|
|
|
|
int Ins(int, int);
|
|
int Del(int, int);
|
|
|
|
private:
|
|
enum { kMaxData = 15000 };
|
|
char* _refData;
|
|
int _refSize;
|
|
|
|
c4_View _attached;
|
|
c4_View _unattached;
|
|
c4_IntProp _prop;
|
|
|
|
char _seed;
|
|
|
|
CResizer (const CResizer&); // not implemented
|
|
void operator= (const CResizer&); // not implemented
|
|
};
|
|
|
|
CResizer::CResizer (const char* file)
|
|
: c4_Storage (file, 1), _refSize (0), _prop ("p1"), _seed (0)
|
|
{
|
|
SetStructure("a[p1:I]");
|
|
|
|
_refData = new char [kMaxData];
|
|
|
|
_attached = View("a");
|
|
|
|
Verify();
|
|
}
|
|
|
|
CResizer::~CResizer ()
|
|
{
|
|
Verify();
|
|
|
|
Commit();
|
|
|
|
Verify();
|
|
|
|
delete [] _refData;
|
|
}
|
|
|
|
void CResizer::Verify()
|
|
{
|
|
int i;
|
|
|
|
A(_refSize == _unattached.GetSize());
|
|
A(_refSize == _attached.GetSize());
|
|
|
|
for (i = 0; i < _refSize; ++i)
|
|
{
|
|
A(_refData[i] == _prop (_unattached[i]));
|
|
A(_refData[i] == _prop (_attached[i]));
|
|
}
|
|
}
|
|
|
|
int CResizer::Ins(int pos_, int cnt_)
|
|
{
|
|
A(pos_ <= _refSize);
|
|
A(_refSize + cnt_ < kMaxData);
|
|
|
|
memmove(_refData + pos_ + cnt_, _refData + pos_, _refSize - pos_);
|
|
_refSize += cnt_;
|
|
|
|
c4_Row row;
|
|
_unattached.InsertAt(pos_, row, cnt_);
|
|
_attached.InsertAt(pos_, row, cnt_);
|
|
|
|
for (int i = pos_; i < pos_ + cnt_; ++i)
|
|
{
|
|
_refData[i] = ++_seed;
|
|
_prop (_unattached[i]) = _seed;
|
|
_prop (_attached[i]) = _seed;
|
|
|
|
if (_seed >= 123)
|
|
_seed = 0;
|
|
}
|
|
|
|
Verify();
|
|
|
|
return _refSize;
|
|
}
|
|
|
|
int CResizer::Del(int pos_, int cnt_)
|
|
{
|
|
A(pos_ + cnt_ <= _refSize);
|
|
|
|
_refSize -= cnt_;
|
|
memmove(_refData + pos_, _refData + pos_ + cnt_, _refSize - pos_);
|
|
|
|
_unattached.RemoveAt(pos_, cnt_);
|
|
_attached.RemoveAt(pos_, cnt_);
|
|
|
|
Verify();
|
|
|
|
return _refSize;
|
|
}
|
|
|
|
void TestResize()
|
|
{
|
|
B(r00, Simple insert, 0) W(r00a);
|
|
{
|
|
CResizer r1 ("r00a");
|
|
|
|
int n = r1.Ins(0, 250);
|
|
A(n == 250);
|
|
|
|
} D(r00a); R(r00a); E;
|
|
|
|
B(r01, Simple removes, 0) W(r01a);
|
|
{
|
|
CResizer r1 ("r01a");
|
|
int n;
|
|
|
|
n = r1.Ins( 0, 500); A(n == 500);
|
|
|
|
n = r1.Del( 0, 50); A(n == 450);
|
|
n = r1.Del( 350, 100); A(n == 350);
|
|
n = r1.Del( 25, 150); A(n == 200);
|
|
n = r1.Del( 0, 200); A(n == 0);
|
|
|
|
n = r1.Ins( 0, 15); A(n == 15);
|
|
|
|
} D(r01a); R(r01a); E;
|
|
|
|
B(r02, Large inserts and removes, 0) W(r02a);
|
|
{
|
|
int big = sizeof (int) == sizeof (short) ? 1000 : 4000;
|
|
|
|
CResizer r1 ("r02a");
|
|
int n;
|
|
|
|
n = r1.Ins( 0, 2000); A(n == 2000);
|
|
n = r1.Ins( 0, 3000); A(n == 5000);
|
|
n = r1.Ins(5000, 1000 + big); A(n == 6000 + big);
|
|
n = r1.Ins( 100, 10); A(n == 6010 + big);
|
|
n = r1.Ins(4000, 100); A(n == 6110 + big);
|
|
n = r1.Ins( 0, 1001); A(n == 7111 + big);
|
|
|
|
n = r1.Del(7111, big); A(n == 7111);
|
|
n = r1.Del( 0, 4111); A(n == 3000);
|
|
n = r1.Del( 10, 10); A(n == 2990);
|
|
n = r1.Del( 10, 10); A(n == 2980);
|
|
n = r1.Del( 5, 10); A(n == 2970);
|
|
n = r1.Del( 0, 990); A(n == 1980);
|
|
n = r1.Del( 3, 1975); A(n == 5);
|
|
|
|
} D(r02a); R(r02a); E;
|
|
|
|
B(r03, Binary property insertions, 0) W(r03a);
|
|
{
|
|
c4_BytesProp p1 ("p1");
|
|
c4_Storage s1 ("r03a", 1);
|
|
s1.SetStructure("a[p1:B]");
|
|
c4_View v1 = s1.View("a");
|
|
|
|
char buf [1024];
|
|
|
|
memset(buf, 0x11, sizeof buf);
|
|
v1.Add(p1 [c4_Bytes (buf, sizeof buf)]);
|
|
|
|
memset(buf, 0x22, sizeof buf);
|
|
v1.Add(p1 [c4_Bytes (buf, sizeof buf / 2)]);
|
|
|
|
s1.Commit();
|
|
|
|
memset(buf, 0x33, sizeof buf);
|
|
p1 (v1[1]) = c4_Bytes (buf, sizeof buf); // fix c4_Column::CopyData
|
|
|
|
memset(buf, 0x44, sizeof buf);
|
|
v1.Add(p1 [c4_Bytes (buf, sizeof buf / 3)]);
|
|
|
|
s1.Commit();
|
|
|
|
memset(buf, 0x55, sizeof buf);
|
|
v1.InsertAt(1, p1 [c4_Bytes (buf, sizeof buf)]);
|
|
|
|
memset(buf, 0x66, sizeof buf);
|
|
v1.InsertAt(1, p1 [c4_Bytes (buf, sizeof buf / 4)]);
|
|
|
|
s1.Commit();
|
|
|
|
} D(r03a); R(r03a); E;
|
|
|
|
B(r04, Scripted string property tests, 0) W(r04a);
|
|
{
|
|
c4_StringProp p1 ("p1");
|
|
c4_Storage s1 ("r04a", 1);
|
|
s1.SetStructure("a[p1:S]");
|
|
|
|
// This code implements a tiny language to specify tests in:
|
|
//
|
|
// "<X>,<Y>A" add X partial buffers of size Y
|
|
// "<X>a" add X full buffers at end
|
|
// "<X>,<Y>C" change entry X to a partial buffer of size Y
|
|
// "<X>c" change entry at position X to a full buffer
|
|
// "<X>,<Y>I" insert partial buffer of size Y at position X
|
|
// "<X>i" insert a full buffer at position X
|
|
// "<X>,<Y>R" remove Y entries at position X
|
|
// "<X>r" remove one entry at position X
|
|
//
|
|
// ">" commit changes
|
|
// "<" rollback changes
|
|
//
|
|
// " " ignore spaces
|
|
// "<X>," for additional args
|
|
// "<X>=" verify number of rows is X
|
|
|
|
const char* scripts [] =
|
|
{
|
|
// A B C D E F G H I J
|
|
"5a 5a 5a 1r 5r 10r 6r 2r > 10=",
|
|
"5a 5a 5a 1,200C 5,200C 10,200C 6,200C 2,200C > 15=",
|
|
"5a 5a 5a 1,300C 5,300C 10,300C 6,300C 2,300C > 15=",
|
|
|
|
// A B C D E F G H I J
|
|
"50a 50a 50a 10r 50r 100r 60r 20r > 145=",
|
|
"50a 50a 50a 10,200C 50,200C 100,200C 60,200C 20,200C > 150=",
|
|
"50a 50a 50a 10,300C 50,300C 100,300C 60,300C 20,300C > 150=",
|
|
|
|
// A B C D E F G H I J
|
|
"50,0A 50,0A 50,0A 10c 50c 100c 60c 20c > 150=", // asserts in 1.7b1
|
|
|
|
// A B C D E
|
|
"3,3A 1,10C 1,1C > 3=", // asserts in 1.7 - June 6 build
|
|
|
|
"",
|
|
0
|
|
};
|
|
|
|
for (int i = 0; scripts[i]; ++i)
|
|
{
|
|
c4_View v1 = s1.View("a");
|
|
v1.RemoveAll();
|
|
s1.Commit();
|
|
A(v1.GetSize() == 0); // start with a clean slate each time
|
|
|
|
const char* p = scripts[i];
|
|
|
|
char fill = '@';
|
|
int save = 0;
|
|
c4_Row row;
|
|
|
|
while (*p)
|
|
{
|
|
// default is a string of 255 chars (with additional null byte)
|
|
p1 (row) = c4_String (++fill, 255);
|
|
|
|
int arg = (int) strtol(p, (char**) &p, 10); // loses const
|
|
|
|
switch (*p++)
|
|
{
|
|
case 'A': p1 (row) = c4_String (fill, arg); arg = save;
|
|
case 'a': while (--arg >= 0) v1.Add(row); break;
|
|
case 'C': p1 (row) = c4_String (fill, arg); arg = save;
|
|
case 'c': v1.SetAt(arg, row); break;
|
|
case 'I': p1 (row) = c4_String (fill, arg); arg = save;
|
|
case 'i': v1.InsertAt(arg, row); break;
|
|
case 'R': v1.RemoveAt(save, arg); break;
|
|
case 'r': v1.RemoveAt(arg); break;
|
|
case '>': s1.Commit(); break;
|
|
case '<': s1.Rollback(); v1 = s1.View("a"); break;
|
|
case ' ': break;
|
|
case ',': save = arg; break;
|
|
case '=': A(v1.GetSize() == arg); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
s1.Commit();
|
|
|
|
} D(r04a); R(r04a); E;
|
|
}
|