1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "test_precomp.hpp"
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace cv;
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerusing namespace std;
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertypedef  struct  CvTsSimpleSeq
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    schar* array;
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int   count;
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int   max_count;
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int   elem_size;
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} CvTsSimpleSeq;
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic CvTsSimpleSeq*  cvTsCreateSimpleSeq( int max_count, int elem_size )
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvTsSimpleSeq* seq = (CvTsSimpleSeq*)cvAlloc( sizeof(*seq) + max_count * elem_size );
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    seq->elem_size = elem_size;
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    seq->max_count = max_count;
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    seq->count = 0;
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    seq->array = (schar*)(seq + 1);
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return seq;
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void cvTsReleaseSimpleSeq( CvTsSimpleSeq** seq )
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cvFree( seq );
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic schar*  cvTsSimpleSeqElem( CvTsSimpleSeq* seq, int index )
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( 0 <= index && index < seq->count );
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return seq->array + index * seq->elem_size;
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void  cvTsClearSimpleSeq( CvTsSimpleSeq* seq )
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    seq->count = 0;
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void cvTsSimpleSeqShiftAndCopy( CvTsSimpleSeq* seq, int from_idx, int to_idx, void* elem=0 )
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int elem_size = seq->elem_size;
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( from_idx == to_idx )
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return;
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( (from_idx > to_idx && !elem) || (from_idx < to_idx && elem) );
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( from_idx < seq->count )
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        memmove( seq->array + to_idx*elem_size, seq->array + from_idx*elem_size,
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                (seq->count - from_idx)*elem_size );
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    seq->count += to_idx - from_idx;
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( elem && to_idx > from_idx )
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        memcpy( seq->array + from_idx*elem_size, elem, (to_idx - from_idx)*elem_size );
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void cvTsSimpleSeqInvert( CvTsSimpleSeq* seq )
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i, k, len = seq->count, elem_size = seq->elem_size;
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    schar *data = seq->array, t;
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < len/2; i++ )
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        schar* a = data + i*elem_size;
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        schar* b = data + (len - i - 1)*elem_size;
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( k = 0; k < elem_size; k++ )
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_SWAP( a[k], b[k], t );
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/****************************************************************************************\
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *                                simple cvset implementation                               *
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler \****************************************************************************************/
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertypedef  struct  CvTsSimpleSet
82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    schar* array;
84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int   count, max_count;
85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int   elem_size;
86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int*  free_stack;
87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int   free_count;
88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} CvTsSimpleSet;
89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void  cvTsClearSimpleSet( CvTsSimpleSet* set_header )
92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i;
94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int elem_size = set_header->elem_size;
95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < set_header->max_count; i++ )
97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        set_header->array[i*elem_size] = 0;
99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        set_header->free_stack[i] = set_header->max_count - i - 1;
100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    set_header->free_count = set_header->max_count;
102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    set_header->count = 0;
103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic CvTsSimpleSet*  cvTsCreateSimpleSet( int max_count, int elem_size )
107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvTsSimpleSet* set_header = (CvTsSimpleSet*)cvAlloc( sizeof(*set_header) + max_count *
109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                        (elem_size + 1 + sizeof(int)));
110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    set_header->elem_size = elem_size + 1;
111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    set_header->max_count = max_count;
112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    set_header->free_stack = (int*)(set_header + 1);
113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    set_header->array = (schar*)(set_header->free_stack + max_count);
114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cvTsClearSimpleSet( set_header );
116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return set_header;
117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void cvTsReleaseSimpleSet( CvTsSimpleSet** set_header )
121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cvFree( set_header );
123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic schar*  cvTsSimpleSetFind( CvTsSimpleSet* set_header, int index )
127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int idx = index * set_header->elem_size;
129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( 0 <= index && index < set_header->max_count );
130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return set_header->array[idx] ? set_header->array + idx + 1 : 0;
131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int  cvTsSimpleSetAdd( CvTsSimpleSet* set_header, void* elem )
135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int idx, idx2;
137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( set_header->free_count > 0 );
138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    idx = set_header->free_stack[--set_header->free_count];
140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    idx2 = idx * set_header->elem_size;
141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( set_header->array[idx2] == 0 );
142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    set_header->array[idx2] = 1;
143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( set_header->elem_size > 1 )
144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        memcpy( set_header->array + idx2 + 1, elem, set_header->elem_size - 1 );
145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    set_header->count = MAX( set_header->count, idx + 1 );
146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return idx;
148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void  cvTsSimpleSetRemove( CvTsSimpleSet* set_header, int index )
152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( set_header->free_count < set_header->max_count &&
154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           0 <= index && index < set_header->max_count );
155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( set_header->array[index * set_header->elem_size] == 1 );
156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    set_header->free_stack[set_header->free_count++] = index;
158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    set_header->array[index * set_header->elem_size] = 0;
159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/****************************************************************************************\
163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *                              simple graph implementation                               *
164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler \****************************************************************************************/
165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslertypedef  struct  CvTsSimpleGraph
167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    char* matrix;
169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int   edge_size;
170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int   oriented;
171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvTsSimpleSet* vtx;
172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} CvTsSimpleGraph;
173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void  cvTsClearSimpleGraph( CvTsSimpleGraph* graph )
176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int max_vtx_count = graph->vtx->max_count;
178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cvTsClearSimpleSet( graph->vtx );
179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    memset( graph->matrix, 0, max_vtx_count * max_vtx_count * graph->edge_size );
180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic CvTsSimpleGraph*  cvTsCreateSimpleGraph( int max_vtx_count, int vtx_size,
184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                               int edge_size, int oriented )
185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvTsSimpleGraph* graph;
187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( max_vtx_count > 1 && vtx_size >= 0 && edge_size >= 0 );
189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    graph = (CvTsSimpleGraph*)cvAlloc( sizeof(*graph) +
190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      max_vtx_count * max_vtx_count * (edge_size + 1));
191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    graph->vtx = cvTsCreateSimpleSet( max_vtx_count, vtx_size );
192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    graph->edge_size = edge_size + 1;
193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    graph->matrix = (char*)(graph + 1);
194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    graph->oriented = oriented;
195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cvTsClearSimpleGraph( graph );
197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return graph;
198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void cvTsReleaseSimpleGraph( CvTsSimpleGraph** graph )
202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( *graph )
204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cvTsReleaseSimpleSet( &(graph[0]->vtx) );
206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cvFree( graph );
207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int  cvTsSimpleGraphAddVertex( CvTsSimpleGraph* graph, void* vertex )
212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return cvTsSimpleSetAdd( graph->vtx, vertex );
214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void  cvTsSimpleGraphRemoveVertex( CvTsSimpleGraph* graph, int index )
218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i, max_vtx_count = graph->vtx->max_count;
220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int edge_size = graph->edge_size;
221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cvTsSimpleSetRemove( graph->vtx, index );
222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /* remove all the corresponding edges */
224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < max_vtx_count; i++ )
225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        graph->matrix[(i*max_vtx_count + index)*edge_size] =
227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        graph->matrix[(index*max_vtx_count + i)*edge_size] = 0;
228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void cvTsSimpleGraphAddEdge( CvTsSimpleGraph* graph, int idx1, int idx2, void* edge )
233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i, t, n = graph->oriented ? 1 : 2;
235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( cvTsSimpleSetFind( graph->vtx, idx1 ) &&
237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           cvTsSimpleSetFind( graph->vtx, idx2 ));
238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < n; i++ )
240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int ofs = (idx1*graph->vtx->max_count + idx2)*graph->edge_size;
242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        assert( graph->matrix[ofs] == 0 );
243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        graph->matrix[ofs] = 1;
244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( graph->edge_size > 1 )
245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            memcpy( graph->matrix + ofs + 1, edge, graph->edge_size - 1 );
246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_SWAP( idx1, idx2, t );
248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void  cvTsSimpleGraphRemoveEdge( CvTsSimpleGraph* graph, int idx1, int idx2 )
253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i, t, n = graph->oriented ? 1 : 2;
255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( cvTsSimpleSetFind( graph->vtx, idx1 ) &&
257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler           cvTsSimpleSetFind( graph->vtx, idx2 ));
258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < n; i++ )
260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int ofs = (idx1*graph->vtx->max_count + idx2)*graph->edge_size;
262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        assert( graph->matrix[ofs] == 1 );
263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        graph->matrix[ofs] = 0;
264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_SWAP( idx1, idx2, t );
265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic schar*  cvTsSimpleGraphFindVertex( CvTsSimpleGraph* graph, int index )
270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return cvTsSimpleSetFind( graph->vtx, index );
272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic char*  cvTsSimpleGraphFindEdge( CvTsSimpleGraph* graph, int idx1, int idx2 )
276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( cvTsSimpleGraphFindVertex( graph, idx1 ) &&
278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler       cvTsSimpleGraphFindVertex( graph, idx2 ))
279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        char* edge = graph->matrix + (idx1 * graph->vtx->max_count + idx2)*graph->edge_size;
281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( edge[0] ) return edge + 1;
282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int  cvTsSimpleGraphVertexDegree( CvTsSimpleGraph* graph, int index )
288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i, count = 0;
290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int edge_size = graph->edge_size;
291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int max_vtx_count = graph->vtx->max_count;
292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( cvTsSimpleGraphFindVertex( graph, index ) != 0 );
293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < max_vtx_count; i++ )
295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        count += graph->matrix[(i*max_vtx_count + index)*edge_size] +
297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        graph->matrix[(index*max_vtx_count + i)*edge_size];
298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !graph->oriented )
301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        assert( count % 2 == 0 );
303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        count /= 2;
304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return count;
306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler///////////////////////////////////// the tests //////////////////////////////////
310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define CV_TS_SEQ_CHECK_CONDITION( expr, err_msg )          \
312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerif( !(expr) )                                               \
313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{                                                           \
314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerset_error_context( #expr, err_msg, __FILE__, __LINE__ );    \
315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );\
316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerthrow -1;                                                   \
317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerclass Core_DynStructBaseTest : public cvtest::BaseTest
320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerpublic:
322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Core_DynStructBaseTest();
323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    virtual ~Core_DynStructBaseTest();
324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bool can_do_fast_forward();
325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void clear();
326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerprotected:
328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int read_params( CvFileStorage* fs );
329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void run_func(void);
330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void set_error_context( const char* condition,
331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                           const char* err_msg,
332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                           const char* file, int line );
333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int test_seq_block_consistence( int _struct_idx, CvSeq* seq, int total );
334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void update_progressbar();
335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int struct_count, max_struct_size, iterations, generations;
337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int min_log_storage_block_size, max_log_storage_block_size;
338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int min_log_elem_size, max_log_elem_size;
339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int gen, struct_idx, iter;
340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int test_progress;
341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int64 start_time;
342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    double cpu_freq;
343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    vector<void*> cxcore_struct;
344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    vector<void*> simple_struct;
345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Ptr<CvMemStorage> storage;
346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
349793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCore_DynStructBaseTest::Core_DynStructBaseTest()
350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct_count = 2;
352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    max_struct_size = 2000;
353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    min_log_storage_block_size = 7;
354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    max_log_storage_block_size = 12;
355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    min_log_elem_size = 0;
356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    max_log_elem_size = 8;
357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    generations = 10;
358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    iterations = max_struct_size*2;
359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    gen = struct_idx = iter = -1;
360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    test_progress = -1;
361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
364793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCore_DynStructBaseTest::~Core_DynStructBaseTest()
365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    clear();
367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_DynStructBaseTest::run_func()
371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool Core_DynStructBaseTest::can_do_fast_forward()
375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return false;
377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_DynStructBaseTest::clear()
381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cvtest::BaseTest::clear();
383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint Core_DynStructBaseTest::read_params( CvFileStorage* fs )
387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int code = cvtest::BaseTest::read_params( fs );
389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    double sqrt_scale = sqrt(ts->get_test_case_count_scale());
390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( code < 0 )
391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return code;
392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct_count = cvReadInt( find_param( fs, "struct_count" ), struct_count );
394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    max_struct_size = cvReadInt( find_param( fs, "max_struct_size" ), max_struct_size );
395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    generations = cvReadInt( find_param( fs, "generations" ), generations );
396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    iterations = cvReadInt( find_param( fs, "iterations" ), iterations );
397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    generations = cvRound(generations*sqrt_scale);
398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    iterations = cvRound(iterations*sqrt_scale);
399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    min_log_storage_block_size = cvReadInt( find_param( fs, "min_log_storage_block_size" ),
401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                           min_log_storage_block_size );
402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    max_log_storage_block_size = cvReadInt( find_param( fs, "max_log_storage_block_size" ),
403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                           max_log_storage_block_size );
404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    min_log_elem_size = cvReadInt( find_param( fs, "min_log_elem_size" ), min_log_elem_size );
405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    max_log_elem_size = cvReadInt( find_param( fs, "max_log_elem_size" ), max_log_elem_size );
406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct_count = cvtest::clipInt( struct_count, 1, 100 );
408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    max_struct_size = cvtest::clipInt( max_struct_size, 1, 1<<20 );
409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    generations = cvtest::clipInt( generations, 1, 100 );
410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    iterations = cvtest::clipInt( iterations, 100, 1<<20 );
411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    min_log_storage_block_size = cvtest::clipInt( min_log_storage_block_size, 7, 20 );
413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    max_log_storage_block_size = cvtest::clipInt( max_log_storage_block_size,
414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                             min_log_storage_block_size, 20 );
415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    min_log_elem_size = cvtest::clipInt( min_log_elem_size, 0, 8 );
417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    max_log_elem_size = cvtest::clipInt( max_log_elem_size, min_log_elem_size, 10 );
418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_DynStructBaseTest::update_progressbar()
424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int64 t;
426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( test_progress < 0 )
428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        test_progress = 0;
430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cpu_freq = cv::getTickFrequency();
431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        start_time = cv::getTickCount();
432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    t = cv::getTickCount();
435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    test_progress = update_progress( test_progress, 0, 0, (double)(t - start_time)/cpu_freq );
436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_DynStructBaseTest::set_error_context( const char* condition,
440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                const char* err_msg,
441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                const char* filename, int lineno )
442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ts->printf( cvtest::TS::LOG, "file %s, line %d: %s\n(\"%s\" failed).\n"
444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler               "generation = %d, struct_idx = %d, iter = %d\n",
445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler               filename, lineno, err_msg, condition, gen, struct_idx, iter );
446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint Core_DynStructBaseTest::test_seq_block_consistence( int _struct_idx, CvSeq* seq, int total )
451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int sum = 0;
453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct_idx = _struct_idx;
454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_TS_SEQ_CHECK_CONDITION( seq != 0, "Null sequence pointer" );
456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( seq->first )
458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvSeqBlock* block = seq->first;
460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvSeqBlock* prev_block = block->prev;
461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int delta_idx = seq->first->start_index;
463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( ;; )
465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( sum == block->start_index - delta_idx &&
467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      block->count > 0 && block->prev == prev_block &&
468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      prev_block->next == block,
469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "sequence blocks are inconsistent" );
470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            sum += block->count;
471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            prev_block = block;
472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            block = block->next;
473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( block == seq->first ) break;
474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_TS_SEQ_CHECK_CONDITION( block->prev->count * seq->elem_size +
477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                  block->prev->data <= seq->block_max,
478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                  "block->data or block_max pointer are incorrect" );
479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_TS_SEQ_CHECK_CONDITION( seq->total == sum && sum == total,
482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                              "total number of elements is incorrect" );
483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/////////////////////////////////// sequence tests ////////////////////////////////////
489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerclass Core_SeqBaseTest : public Core_DynStructBaseTest
491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerpublic:
493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Core_SeqBaseTest();
494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void clear();
495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void run( int );
496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerprotected:
498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int test_multi_create();
499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int test_get_seq_elem( int _struct_idx, int iters );
500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int test_get_seq_reading( int _struct_idx, int iters );
501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int test_seq_ops( int iters );
502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
505793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCore_SeqBaseTest::Core_SeqBaseTest()
506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_SeqBaseTest::clear()
511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( size_t i = 0; i < simple_struct.size(); i++ )
513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cvTsReleaseSimpleSeq( (CvTsSimpleSeq**)&simple_struct[i] );
514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Core_DynStructBaseTest::clear();
515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint Core_SeqBaseTest::test_multi_create()
519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    vector<CvSeqWriter> writer(struct_count);
521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    vector<int> pos(struct_count);
522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    vector<int> index(struct_count);
523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int  cur_count, elem_size;
524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    RNG& rng = ts->get_rng();
525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( int i = 0; i < struct_count; i++ )
527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double t;
529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvTsSimpleSeq* sseq;
530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pos[i] = -1;
532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        index[i] = i;
533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        t = cvtest::randReal(rng)*(max_log_elem_size - min_log_elem_size) + min_log_elem_size;
535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        elem_size = cvRound( exp(t * CV_LOG2) );
536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        elem_size = MIN( elem_size, (int)(storage->block_size - sizeof(void*) -
537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                          sizeof(CvSeqBlock) - sizeof(CvMemBlock)) );
538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cvTsReleaseSimpleSeq( (CvTsSimpleSeq**)&simple_struct[i] );
540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        simple_struct[i] = sseq = cvTsCreateSimpleSeq( max_struct_size, elem_size );
541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cxcore_struct[i] = 0;
542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        sseq->count = cvtest::randInt( rng ) % max_struct_size;
543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        Mat m( 1, MAX(sseq->count,1)*elem_size, CV_8UC1, sseq->array );
544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cvtest::randUni( rng, m, Scalar::all(0), Scalar::all(256) );
545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( cur_count = struct_count; cur_count > 0; cur_count-- )
548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for(;;)
550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int k = cvtest::randInt( rng ) % cur_count;
552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            struct_idx = index[k];
553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[struct_idx];
554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( pos[struct_idx] < 0 )
556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int hdr_size = (cvtest::randInt(rng) % 10)*4 + sizeof(CvSeq);
558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                hdr_size = MIN( hdr_size, (int)(storage->block_size - sizeof(CvMemBlock)) );
559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                elem_size = sseq->elem_size;
560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( cvtest::randInt(rng) % 2 )
562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvStartWriteSeq( 0, hdr_size, elem_size, storage, &writer[struct_idx] );
564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CvSeq* s;
568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    s = cvCreateSeq( 0, hdr_size, elem_size, storage );
569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvStartAppendToSeq( s, &writer[struct_idx] );
570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvSetSeqBlockSize( writer[struct_idx].seq, cvtest::randInt( rng ) % 10000 );
573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pos[struct_idx] = 0;
574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            update_progressbar();
577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( pos[struct_idx] == sseq->count )
578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cxcore_struct[struct_idx] = cvEndWriteSeq( &writer[struct_idx] );
580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                /* del index */
581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                for( ; k < cur_count-1; k++ )
582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    index[k] = index[k+1];
583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                schar* el = cvTsSimpleSeqElem( sseq, pos[struct_idx] );
588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_WRITE_SEQ_ELEM_VAR( el, writer[struct_idx] );
589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pos[struct_idx]++;
591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint  Core_SeqBaseTest::test_get_seq_elem( int _struct_idx, int iters )
599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    RNG& rng = ts->get_rng();
601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvSeq* seq = (CvSeq*)cxcore_struct[_struct_idx];
603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[_struct_idx];
604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct_idx = _struct_idx;
605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( seq->total == sseq->count );
607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( sseq->count == 0 )
609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return 0;
610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( int i = 0; i < iters; i++ )
612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int idx = cvtest::randInt(rng) % (sseq->count*3) - sseq->count*3/2;
614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int idx0 = (unsigned)idx < (unsigned)(sseq->count) ? idx : idx < 0 ?
615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        idx + sseq->count : idx - sseq->count;
616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int bad_range = (unsigned)idx0 >= (unsigned)(sseq->count);
617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        schar* elem;
618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler         elem = cvGetSeqElem( seq, idx );
619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( bad_range )
621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( elem == 0,
623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "cvGetSeqElem doesn't "
624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "handle \"out of range\" properly" );
625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else
627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( elem != 0 &&
629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      !memcmp( elem, cvTsSimpleSeqElem(sseq, idx0), sseq->elem_size ),
630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "cvGetSeqElem returns wrong element" );
631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             idx = cvSeqElemIdx(seq, elem );
633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( idx >= 0 && idx == idx0,
634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "cvSeqElemIdx is incorrect" );
635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint  Core_SeqBaseTest::test_get_seq_reading( int _struct_idx, int iters )
643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const int max_val = 3*5 + 2;
645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvSeq* seq = (CvSeq*)cxcore_struct[_struct_idx];
646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[_struct_idx];
647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int total = seq->total;
648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    RNG& rng = ts->get_rng();
649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvSeqReader reader;
650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    vector<schar> _elem(sseq->elem_size);
651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    schar* elem = &_elem[0];
652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( total == sseq->count );
654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    this->struct_idx = _struct_idx;
655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int pos = cvtest::randInt(rng) % 2;
657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cvStartReadSeq( seq, &reader, pos );
658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( total == 0 )
660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_TS_SEQ_CHECK_CONDITION( reader.ptr == 0, "Empty sequence reader pointer is not NULL" );
662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return 0;
663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pos = pos ? seq->total - 1 : 0;
666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CV_TS_SEQ_CHECK_CONDITION( pos == cvGetSeqReaderPos(&reader),
668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                              "initial reader position is wrong" );
669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( iter = 0; iter < iters; iter++ )
671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int op = cvtest::randInt(rng) % max_val;
673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( op >= max_val - 2 )
675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int new_pos, new_pos0;
677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int bad_range;
678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int is_relative = op == max_val - 1;
679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            new_pos = cvtest::randInt(rng) % (total*2) - total;
681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            new_pos0 = new_pos + (is_relative ? pos : 0 );
682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( new_pos0 < 0 ) new_pos0 += total;
684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( new_pos0 >= total ) new_pos0 -= total;
685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            bad_range = (unsigned)new_pos0 >= (unsigned)total;
687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             cvSetSeqReaderPos( &reader, new_pos, is_relative );
688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( !bad_range )
690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_TS_SEQ_CHECK_CONDITION( new_pos0 == cvGetSeqReaderPos( &reader ),
692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                          "cvset reader position doesn't work" );
693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pos = new_pos0;
694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_TS_SEQ_CHECK_CONDITION( pos == cvGetSeqReaderPos( &reader ),
698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                          "reader doesn't stay at the current position after wrong positioning" );
699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else
702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int direction = (op % 3) - 1;
704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            memcpy( elem, reader.ptr, sseq->elem_size );
705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( direction > 0 )
707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_NEXT_SEQ_ELEM( sseq->elem_size, reader );
709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if( direction < 0 )
711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_PREV_SEQ_ELEM( sseq->elem_size, reader );
713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( memcmp(elem, cvTsSimpleSeqElem(sseq, pos),
716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              sseq->elem_size) == 0, "reading is incorrect" );
717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pos += direction;
718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( -pos > 0 ) pos += total;
719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( pos >= total ) pos -= total;
720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( pos == cvGetSeqReaderPos( &reader ),
722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "reader doesn't move correctly after reading" );
723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint  Core_SeqBaseTest::test_seq_ops( int iters )
731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const int max_op = 14;
733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int max_elem_size = 0;
734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    schar* elem2 = 0;
735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    RNG& rng = ts->get_rng();
736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( int i = 0; i < struct_count; i++ )
738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        max_elem_size = MAX( max_elem_size, ((CvSeq*)cxcore_struct[i])->elem_size );
739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    vector<schar> elem_buf(max_struct_size*max_elem_size);
741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    schar* elem = (schar*)&elem_buf[0];
742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Mat elem_mat;
743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( iter = 0; iter < iters; iter++ )
745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        struct_idx = cvtest::randInt(rng) % struct_count;
747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int op = cvtest::randInt(rng) % max_op;
748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvSeq* seq = (CvSeq*)cxcore_struct[struct_idx];
749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[struct_idx];
750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int elem_size = sseq->elem_size;
751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int whence = 0, pos = 0, count = 0;
752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        switch( op )
754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 0:
756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 1:
757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 2:  // push/pushfront/insert
758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( sseq->count == sseq->max_count )
759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                elem_mat = Mat(1, elem_size, CV_8U, elem);
762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvtest::randUni( rng, elem_mat, cvScalarAll(0), cvScalarAll(255) );
763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                whence = op - 1;
765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( whence < 0 )
766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    pos = 0;
768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvSeqPushFront( seq, elem );
769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else if( whence > 0 )
771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    pos = sseq->count;
773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvSeqPush( seq, elem );
774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    pos = cvtest::randInt(rng) % (sseq->count + 1);
778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvSeqInsert( seq, pos, elem );
779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvTsSimpleSeqShiftAndCopy( sseq, pos, pos + 1, elem );
782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                elem2 = cvGetSeqElem( seq, pos );
783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_TS_SEQ_CHECK_CONDITION( elem2 != 0, "The inserted element could not be retrieved" );
784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_TS_SEQ_CHECK_CONDITION( seq->total == sseq->count &&
785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                          memcmp(elem2, cvTsSimpleSeqElem(sseq,pos), elem_size) == 0,
786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                          "The inserted sequence element is wrong" );
787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 3:
790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 4:
791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 5: // pop/popfront/remove
792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( sseq->count == 0 )
793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                whence = op - 4;
796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( whence < 0 )
797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    pos = 0;
799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     cvSeqPopFront( seq, elem );
800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else if( whence > 0 )
802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    pos = sseq->count-1;
804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     cvSeqPop( seq, elem );
805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    pos = cvtest::randInt(rng) % sseq->count;
809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     cvSeqRemove( seq, pos );
810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( whence != 0 )
813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( seq->total == sseq->count - 1 &&
814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              memcmp( elem, cvTsSimpleSeqElem(sseq,pos), elem_size) == 0,
815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "The popped sequence element isn't correct" );
816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvTsSimpleSeqShiftAndCopy( sseq, pos + 1, pos );
818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( sseq->count > 0 )
820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     elem2 = cvGetSeqElem( seq, pos < sseq->count ? pos : -1 );
822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( elem2 != 0, "GetSeqElem fails after removing the element" );
823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( memcmp( elem2,
825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                      cvTsSimpleSeqElem(sseq, pos - (pos == sseq->count)), elem_size) == 0,
826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "The first shifted element is not correct after removing another element" );
827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( seq->first == 0,
831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "The sequence doesn't become empty after the final remove" );
832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 6:
836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 7:
837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 8: // push [front] multi/insert slice
838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( sseq->count == sseq->max_count )
839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                count = cvtest::randInt( rng ) % (sseq->max_count - sseq->count + 1);
842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                elem_mat = Mat(1, MAX(count,1) * elem_size, CV_8U, elem);
843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvtest::randUni( rng, elem_mat, cvScalarAll(0), cvScalarAll(255) );
844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                whence = op - 7;
846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pos = whence < 0 ? 0 : whence > 0 ? sseq->count : (int)(cvtest::randInt(rng) % (sseq->count+1));
847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( whence != 0 )
848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     cvSeqPushMulti( seq, elem, count, whence < 0 );
850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CvSeq header;
854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CvSeqBlock block;
855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvMakeSeqHeaderForArray( CV_SEQ_KIND_GENERIC, sizeof(CvSeq),
856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                     sseq->elem_size,
857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                     elem, count,
858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                     &header, &block );
859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvSeqInsertSlice( seq, pos, &header );
861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvTsSimpleSeqShiftAndCopy( sseq, pos, pos + count, elem );
863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( sseq->count > 0 )
865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    // choose the random element among the added
867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    pos = count > 0 ? (int)(cvtest::randInt(rng) % count + pos) : MAX(pos-1,0);
868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    elem2 = cvGetSeqElem( seq, pos );
869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( elem2 != 0, "multi push operation doesn't add elements" );
870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( seq->total == sseq->count &&
871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              memcmp( elem2, cvTsSimpleSeqElem(sseq,pos), elem_size) == 0,
872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "One of the added elements is wrong" );
873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( seq->total == 0 && seq->first == 0,
877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "Adding no elements to empty sequence fails" );
878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 9:
882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 10:
883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 11: // pop [front] multi
884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( sseq->count == 0 )
885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                count = cvtest::randInt(rng) % (sseq->count+1);
888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                whence = op - 10;
889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pos = whence < 0 ? 0 : whence > 0 ? sseq->count - count :
890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    (int)(cvtest::randInt(rng) % (sseq->count - count + 1));
891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( whence != 0 )
893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     cvSeqPopMulti( seq, elem, count, whence < 0 );
895793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( count > 0 )
897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        CV_TS_SEQ_CHECK_CONDITION( memcmp(elem,
899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                          cvTsSimpleSeqElem(sseq,pos), elem_size) == 0,
900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  "The first (in the sequence order) removed element is wrong after popmulti" );
901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     cvSeqRemoveSlice( seq, cvSlice(pos, pos + count) );
906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_TS_SEQ_CHECK_CONDITION( seq->total == sseq->count - count,
909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                          "The popmulti left a wrong number of elements in the sequence" );
910793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvTsSimpleSeqShiftAndCopy( sseq, pos + count, pos, 0 );
912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( sseq->count > 0 )
913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
914793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    pos = whence < 0 ? 0 : MIN( pos, sseq->count - 1 );
915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    elem2 = cvGetSeqElem( seq, pos );
916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( elem2 &&
917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              memcmp( elem2, cvTsSimpleSeqElem(sseq,pos), elem_size) == 0,
918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "The last sequence element is wrong after POP" );
919793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
922793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( seq->total == 0 && seq->first == 0,
923793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "The sequence doesn't become empty after final POP" );
924793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
925793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
926793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 12: // seqslice
927793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
928793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CvMemStoragePos storage_pos;
929793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvSaveMemStoragePos( storage, &storage_pos );
930793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
931793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int copy_data = cvtest::randInt(rng) % 2;
932793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                count = cvtest::randInt(rng) % (seq->total + 1);
933793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pos = cvtest::randInt(rng) % (seq->total - count + 1);
934793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CvSeq* seq_slice = cvSeqSlice( seq, cvSlice(pos, pos + count), storage, copy_data );
935793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
936793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_TS_SEQ_CHECK_CONDITION( seq_slice && seq_slice->total == count,
937793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                          "cvSeqSlice returned incorrect slice" );
938793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
939793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( count > 0 )
940793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
941793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    int test_idx = cvtest::randInt(rng) % count;
942793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    elem2 = cvGetSeqElem( seq_slice, test_idx );
943793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    schar* elem3 = cvGetSeqElem( seq, pos + test_idx );
944793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( elem2 &&
945793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              memcmp( elem2, cvTsSimpleSeqElem(sseq,pos + test_idx), elem_size) == 0,
946793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "The extracted slice elements are not correct" );
947793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( (elem2 == elem3) ^ copy_data,
948793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "copy_data flag is handled incorrectly" );
949793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
950793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
951793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvRestoreMemStoragePos( storage, &storage_pos );
952793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
953793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
954793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 13: // clear
955793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvTsClearSimpleSeq( sseq );
956793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvClearSeq( seq );
957793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_TS_SEQ_CHECK_CONDITION( seq->total == 0 && seq->first == 0,
958793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                          "The sequence doesn't become empty after clear" );
959793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
960793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            default:
961793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                assert(0);
962793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return -1;
963793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
964793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
965793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( test_seq_block_consistence(struct_idx, seq, sseq->count) < 0 )
966793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return -1;
967793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
968793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( test_get_seq_elem(struct_idx, 7) < 0 )
969793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return -1;
970793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
971793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        update_progressbar();
972793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
973793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
974793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
975793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
976793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
977793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
978793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_SeqBaseTest::run( int )
979793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
980793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    try
981793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
982793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        RNG& rng = ts->get_rng();
983793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int i;
984793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double t;
985793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
986793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        clear();
987793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        test_progress = -1;
988793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
989793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        simple_struct.resize(struct_count, 0);
990793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cxcore_struct.resize(struct_count, 0);
991793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
992793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( gen = 0; gen < generations; gen++ )
993793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
994793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            struct_idx = iter = -1;
995793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
996793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( !storage )
997793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
998793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size)
999793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                + min_log_storage_block_size;
1000793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                storage.reset(cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) ));
1001793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1002793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1003793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            iter = struct_idx = -1;
1004793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            test_multi_create();
1005793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1006793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( i = 0; i < struct_count; i++ )
1007793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1008793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( test_seq_block_consistence(i, (CvSeq*)cxcore_struct[i],
1009793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                               ((CvTsSimpleSeq*)simple_struct[i])->count) < 0 )
1010793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    return;
1011793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1012793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( test_get_seq_elem( i, MAX(iterations/3,7) ) < 0 )
1013793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    return;
1014793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1015793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( test_get_seq_reading( i, MAX(iterations/3,7) ) < 0 )
1016793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    return;
1017793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                update_progressbar();
1018793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1019793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1020793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( test_seq_ops( iterations ) < 0 )
1021793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return;
1022793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1023793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( cvtest::randInt(rng) % 2 )
1024793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                storage.release();
1025793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
1026793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvClearMemStorage( storage );
1027793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1028793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1029793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    catch(int)
1030793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1031793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1032793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1033793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1034793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1035793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler////////////////////////////// more sequence tests //////////////////////////////////////
1036793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1037793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerclass Core_SeqSortInvTest : public Core_SeqBaseTest
1038793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1039793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerpublic:
1040793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Core_SeqSortInvTest();
1041793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void run( int );
1042793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1043793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerprotected:
1044793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
1045793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1046793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1047793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCore_SeqSortInvTest::Core_SeqSortInvTest()
1048793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1049793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1050793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1051793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1052793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int icvCmpSeqElems( const void* a, const void* b, void* userdata )
1053793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1054793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return memcmp( a, b, ((CvSeq*)userdata)->elem_size );
1055793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1056793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1057793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int icvCmpSeqElems2_elem_size = 0;
1058793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int icvCmpSeqElems2( const void* a, const void* b )
1059793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1060793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return memcmp( a, b, icvCmpSeqElems2_elem_size );
1061793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1062793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1063793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1064793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_SeqSortInvTest::run( int )
1065793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1066793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    try
1067793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1068793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        RNG& rng = ts->get_rng();
1069793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int i, k;
1070793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double t;
1071793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        schar *elem0, *elem, *elem2;
1072793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        vector<uchar> buffer;
1073793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1074793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        clear();
1075793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        test_progress = -1;
1076793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1077793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        simple_struct.resize(struct_count, 0);
1078793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cxcore_struct.resize(struct_count, 0);
1079793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1080793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( gen = 0; gen < generations; gen++ )
1081793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1082793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            struct_idx = iter = -1;
1083793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1084793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( !storage )
1085793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1086793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size)
1087793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                + min_log_storage_block_size;
1088793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                storage.reset(cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) ));
1089793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1090793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1091793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( iter = 0; iter < iterations/10; iter++ )
1092793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1093793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int max_size = 0;
1094793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                test_multi_create();
1095793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1096793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                for( i = 0; i < struct_count; i++ )
1097793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
1098793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[i];
1099793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    max_size = MAX( max_size, sseq->count*sseq->elem_size );
1100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                buffer.resize(max_size);
1103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                for( i = 0; i < struct_count; i++ )
1105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
1106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CvSeq* seq = (CvSeq*)cxcore_struct[i];
1107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CvTsSimpleSeq* sseq = (CvTsSimpleSeq*)simple_struct[i];
1108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CvSlice slice = CV_WHOLE_SEQ;
1109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    //printf("%d. %d. %d-th size = %d\n", gen, iter, i, sseq->count );
1111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvSeqInvert( seq );
1113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvTsSimpleSeqInvert( sseq );
1114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( test_seq_block_consistence( i, seq, sseq->count ) < 0 )
1116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        return;
1117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( sseq->count > 0 && cvtest::randInt(rng) % 2 == 0 )
1119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
1120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        slice.end_index = cvtest::randInt(rng) % sseq->count + 1;
1121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        slice.start_index = cvtest::randInt(rng) % (sseq->count - slice.end_index + 1);
1122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        slice.end_index += slice.start_index;
1123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
1124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvCvtSeqToArray( seq, &buffer[0], slice );
1126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    slice.end_index = MIN( slice.end_index, sseq->count );
1128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( sseq->count == 0 || memcmp( &buffer[0],
1129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                                          sseq->array + slice.start_index*sseq->elem_size,
1130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                                          (slice.end_index - slice.start_index)*sseq->elem_size ) == 0,
1131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "cvSeqInvert returned wrong result" );
1132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    for( k = 0; k < (sseq->count > 0 ? 10 : 0); k++ )
1134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
1135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        int idx0 = cvtest::randInt(rng) % sseq->count, idx = 0;
1136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        elem0 = cvTsSimpleSeqElem( sseq, idx0 );
1137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        elem = cvGetSeqElem( seq, idx0 );
1138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        elem2 = cvSeqSearch( seq, elem0, k % 2 ? icvCmpSeqElems : 0, 0, &idx, seq );
1139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        CV_TS_SEQ_CHECK_CONDITION( elem != 0 &&
1141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  memcmp( elem0, elem, seq->elem_size ) == 0,
1142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  "cvSeqInvert gives incorrect result" );
1143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        CV_TS_SEQ_CHECK_CONDITION( elem2 != 0 &&
1144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  memcmp( elem0, elem2, seq->elem_size ) == 0 &&
1145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  elem2 == cvGetSeqElem( seq, idx ),
1146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  "cvSeqSearch failed (linear search)" );
1147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
1148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvSeqSort( seq, icvCmpSeqElems, seq );
1150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( test_seq_block_consistence( i, seq, sseq->count ) < 0 )
1152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        return;
1153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( sseq->count > 0 )
1155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
1156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        // !!! This is not thread-safe !!!
1157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        icvCmpSeqElems2_elem_size = sseq->elem_size;
1158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        qsort( sseq->array, sseq->count, sseq->elem_size, icvCmpSeqElems2 );
1159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        if( cvtest::randInt(rng) % 2 == 0 )
1161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        {
1162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            slice.end_index = cvtest::randInt(rng) % sseq->count + 1;
1163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            slice.start_index = cvtest::randInt(rng) % (sseq->count - slice.end_index + 1);
1164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            slice.end_index += slice.start_index;
1165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        }
1166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
1167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvCvtSeqToArray( seq, &buffer[0], slice );
1169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( sseq->count == 0 || memcmp( &buffer[0],
1170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                                          sseq->array + slice.start_index*sseq->elem_size,
1171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                                          (slice.end_index - slice.start_index)*sseq->elem_size ) == 0,
1172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "cvSeqSort returned wrong result" );
1173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    for( k = 0; k < (sseq->count > 0 ? 10 : 0); k++ )
1175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
1176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        int idx0 = cvtest::randInt(rng) % sseq->count, idx = 0;
1177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        elem0 = cvTsSimpleSeqElem( sseq, idx0 );
1178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        elem = cvGetSeqElem( seq, idx0 );
1179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        elem2 = cvSeqSearch( seq, elem0, icvCmpSeqElems, 1, &idx, seq );
1180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        CV_TS_SEQ_CHECK_CONDITION( elem != 0 &&
1182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  memcmp( elem0, elem, seq->elem_size ) == 0,
1183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  "cvSeqSort gives incorrect result" );
1184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        CV_TS_SEQ_CHECK_CONDITION( elem2 != 0 &&
1185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  memcmp( elem0, elem2, seq->elem_size ) == 0 &&
1186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  elem2 == cvGetSeqElem( seq, idx ),
1187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                  "cvSeqSearch failed (binary search)" );
1188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
1189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvClearMemStorage( storage );
1192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            storage.release();
1195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    catch (int)
1198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/////////////////////////////////////// set tests ///////////////////////////////////////
1204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerclass Core_SetTest : public Core_DynStructBaseTest
1206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerpublic:
1208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Core_SetTest();
1209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void clear();
1210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void run( int );
1211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerprotected:
1213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    //int test_seq_block_consistence( int struct_idx );
1214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int test_set_ops( int iters );
1215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
1216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1218793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCore_SetTest::Core_SetTest()
1219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_SetTest::clear()
1224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( size_t i = 0; i < simple_struct.size(); i++ )
1226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cvTsReleaseSimpleSet( (CvTsSimpleSet**)&simple_struct[i] );
1227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Core_DynStructBaseTest::clear();
1228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint  Core_SetTest::test_set_ops( int iters )
1232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const int max_op = 4;
1234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int max_elem_size = 0;
1235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int idx, idx0;
1236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvSetElem *elem = 0, *elem2 = 0, *elem3 = 0;
1237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    schar* elem_data = 0;
1238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    RNG& rng = ts->get_rng();
1239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    //int max_active_count = 0, mean_active_count = 0;
1240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( int i = 0; i < struct_count; i++ )
1242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        max_elem_size = MAX( max_elem_size, ((CvSeq*)cxcore_struct[i])->elem_size );
1243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    vector<schar> elem_buf(max_elem_size);
1245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Mat elem_mat;
1246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( iter = 0; iter < iters; iter++ )
1248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        struct_idx = cvtest::randInt(rng) % struct_count;
1250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvSet* cvset = (CvSet*)cxcore_struct[struct_idx];
1252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvTsSimpleSet* sset = (CvTsSimpleSet*)simple_struct[struct_idx];
1253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int pure_elem_size = sset->elem_size - 1;
1254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int prev_total = cvset->total, prev_count = cvset->active_count;
1255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int op = cvtest::randInt(rng) % (iter <= iters/10 ? 2 : max_op);
1256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int by_ptr = op % 2 == 0;
1257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvSetElem* first_free = cvset->free_elems;
1258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvSetElem* next_free = first_free ? first_free->next_free : 0;
1259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int pass_data = 0;
1260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( iter > iters/10 && cvtest::randInt(rng)%200 == 0 ) // clear set
1262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            prev_count = cvset->total;
1264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cvClearSet( cvset );
1265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cvTsClearSimpleSet( sset );
1266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( cvset->active_count == 0 && cvset->total == 0 &&
1268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      cvset->first == 0 && cvset->free_elems == 0 &&
1269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (cvset->free_blocks != 0 || prev_count == 0),
1270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "cvClearSet doesn't remove all the elements" );
1271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            continue;
1272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else if( op == 0 || op == 1 ) // add element
1274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( sset->free_count == 0 )
1276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                continue;
1277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            elem_mat = Mat(1, cvset->elem_size, CV_8U, &elem_buf[0]);
1279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cvtest::randUni( rng, elem_mat, cvScalarAll(0), cvScalarAll(255) );
1280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            elem = (CvSetElem*)&elem_buf[0];
1281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( by_ptr )
1283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                elem2 = cvSetNew( cvset );
1285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_TS_SEQ_CHECK_CONDITION( elem2 != 0, "cvSetNew returned NULL pointer" );
1286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
1288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pass_data = cvtest::randInt(rng) % 2;
1290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                idx = cvSetAdd( cvset, pass_data ? elem : 0, &elem2 );
1291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_TS_SEQ_CHECK_CONDITION( elem2 != 0 && elem2->flags == idx,
1292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                          "cvSetAdd returned NULL pointer or a wrong index" );
1293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            elem_data = (schar*)elem + sizeof(int);
1296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( !pass_data )
1298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                memcpy( (schar*)elem2 + sizeof(int), elem_data, pure_elem_size );
1299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            idx = elem2->flags;
1301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            idx0 = cvTsSimpleSetAdd( sset, elem_data );
1302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            elem3 = cvGetSetElem( cvset, idx );
1303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( CV_IS_SET_ELEM(elem3) &&
1305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      idx == idx0 && elem3 == elem2 && (!pass_data ||
1306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                                        memcmp( (char*)elem3 + sizeof(int), elem_data, pure_elem_size) == 0),
1307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The added element is not correct" );
1308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( (!first_free || elem3 == first_free) &&
1310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (!next_free || cvset->free_elems == next_free) &&
1311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      cvset->active_count == prev_count + 1,
1312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The free node list is modified incorrectly" );
1313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else if( op == 2 || op == 3 ) // remove element
1315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            idx = cvtest::randInt(rng) % sset->max_count;
1317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( sset->free_count == sset->max_count || idx >= sset->count )
1319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                continue;
1320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            elem_data = cvTsSimpleSetFind(sset, idx);
1322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( elem_data == 0 )
1323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                continue;
1324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            elem = cvGetSetElem( cvset, idx );
1326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( CV_IS_SET_ELEM(elem) && elem->flags == idx &&
1327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      memcmp((char*)elem + sizeof(int), elem_data, pure_elem_size) == 0,
1328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "cvGetSetElem returned wrong element" );
1329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( by_ptr )
1331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 cvSetRemoveByPtr( cvset, elem );
1333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
1335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 cvSetRemove( cvset, idx );
1337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cvTsSimpleSetRemove( sset, idx );
1340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( !CV_IS_SET_ELEM(elem) && !cvGetSetElem(cvset, idx) &&
1342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (elem->flags & CV_SET_ELEM_IDX_MASK) == idx,
1343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "cvSetRemove[ByPtr] didn't release the element properly" );
1344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( elem->next_free == first_free &&
1346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      cvset->free_elems == elem &&
1347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      cvset->active_count == prev_count - 1,
1348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The free node list has not been updated properly" );
1349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        //max_active_count = MAX( max_active_count, cvset->active_count );
1352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        //mean_active_count += cvset->active_count;
1353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_TS_SEQ_CHECK_CONDITION( cvset->active_count == sset->max_count - sset->free_count &&
1354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                  cvset->total >= cvset->active_count &&
1355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                  (cvset->total == 0 || cvset->total >= prev_total),
1356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                  "The total number of cvset elements is not correct" );
1357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // CvSet and simple set do not necessary have the same "total" (active & free) number,
1359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // so pass "set->total" to skip that check
1360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        test_seq_block_consistence( struct_idx, (CvSeq*)cvset, cvset->total );
1361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        update_progressbar();
1362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
1365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_SetTest::run( int )
1369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    try
1371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        RNG& rng = ts->get_rng();
1373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double t;
1374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        clear();
1376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        test_progress = -1;
1377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        simple_struct.resize(struct_count, 0);
1379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cxcore_struct.resize(struct_count, 0);
1380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( gen = 0; gen < generations; gen++ )
1382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            struct_idx = iter = -1;
1384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size) + min_log_storage_block_size;
1385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            storage.reset(cvCreateMemStorage( cvRound( exp(t * CV_LOG2) ) ));
1386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( int i = 0; i < struct_count; i++ )
1388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                t = cvtest::randReal(rng)*(max_log_elem_size - min_log_elem_size) + min_log_elem_size;
1390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int pure_elem_size = cvRound( exp(t * CV_LOG2) );
1391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int elem_size = pure_elem_size + sizeof(int);
1392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                elem_size = (elem_size + sizeof(size_t) - 1) & ~(sizeof(size_t)-1);
1393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                elem_size = MAX( elem_size, (int)sizeof(CvSetElem) );
1394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                elem_size = MIN( elem_size, (int)(storage->block_size - sizeof(void*) - sizeof(CvMemBlock) - sizeof(CvSeqBlock)) );
1395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pure_elem_size = MIN( pure_elem_size, elem_size-(int)sizeof(CvSetElem) );
1396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvTsReleaseSimpleSet( (CvTsSimpleSet**)&simple_struct[i] );
1398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                simple_struct[i] = cvTsCreateSimpleSet( max_struct_size, pure_elem_size );
1399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cxcore_struct[i] = cvCreateSet( 0, sizeof(CvSet), elem_size, storage );
1400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( test_set_ops( iterations*100 ) < 0 )
1403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return;
1404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            storage.release();
1406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    catch(int)
1409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/////////////////////////////////////// graph tests //////////////////////////////////
1415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerclass Core_GraphTest : public Core_DynStructBaseTest
1417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerpublic:
1419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Core_GraphTest();
1420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void clear();
1421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void run( int );
1422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerprotected:
1424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    //int test_seq_block_consistence( int struct_idx );
1425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int test_graph_ops( int iters );
1426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
1427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1429793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCore_GraphTest::Core_GraphTest()
1430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_GraphTest::clear()
1435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( size_t i = 0; i < simple_struct.size(); i++ )
1437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cvTsReleaseSimpleGraph( (CvTsSimpleGraph**)&simple_struct[i] );
1438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Core_DynStructBaseTest::clear();
1439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint  Core_GraphTest::test_graph_ops( int iters )
1443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    const int max_op = 4;
1445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i, k;
1446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int max_elem_size = 0;
1447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int idx, idx0;
1448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvGraphVtx *vtx = 0, *vtx2 = 0, *vtx3 = 0;
1449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvGraphEdge* edge = 0, *edge2 = 0;
1450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    RNG& rng = ts->get_rng();
1451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    //int max_active_count = 0, mean_active_count = 0;
1452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < struct_count; i++ )
1454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvGraph* graph = (CvGraph*)cxcore_struct[i];
1456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        max_elem_size = MAX( max_elem_size, graph->elem_size );
1457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        max_elem_size = MAX( max_elem_size, graph->edges->elem_size );
1458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    vector<schar> elem_buf(max_elem_size);
1461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Mat elem_mat;
1462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( iter = 0; iter < iters; iter++ )
1464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        struct_idx = cvtest::randInt(rng) % struct_count;
1466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvGraph* graph = (CvGraph*)cxcore_struct[struct_idx];
1467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvTsSimpleGraph* sgraph = (CvTsSimpleGraph*)simple_struct[struct_idx];
1468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvSet* edges = graph->edges;
1469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        schar *vtx_data;
1470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        char *edge_data;
1471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int pure_vtx_size = sgraph->vtx->elem_size - 1,
1472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pure_edge_size = sgraph->edge_size - 1;
1473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int prev_vtx_total = graph->total,
1474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        prev_edge_total = graph->edges->total,
1475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        prev_vtx_count = graph->active_count,
1476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        prev_edge_count = graph->edges->active_count;
1477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int op = cvtest::randInt(rng) % max_op;
1478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int pass_data = 0, vtx_degree0 = 0, vtx_degree = 0;
1479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CvSetElem *first_free, *next_free;
1480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( cvtest::randInt(rng) % 200 == 0 ) // clear graph
1482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int prev_vtx_count2 = graph->total, prev_edge_count2 = graph->edges->total;
1484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cvClearGraph( graph );
1486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cvTsClearSimpleGraph( sgraph );
1487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( graph->active_count == 0 && graph->total == 0 &&
1489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      graph->first == 0 && graph->free_elems == 0 &&
1490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (graph->free_blocks != 0 || prev_vtx_count2 == 0),
1491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The graph is not empty after clearing" );
1492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( edges->active_count == 0 && edges->total == 0 &&
1494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      edges->first == 0 && edges->free_elems == 0 &&
1495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (edges->free_blocks != 0 || prev_edge_count2 == 0),
1496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The graph is not empty after clearing" );
1497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else if( op == 0 ) // add vertex
1499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( sgraph->vtx->free_count == 0 )
1501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                continue;
1502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            first_free = graph->free_elems;
1504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            next_free = first_free ? first_free->next_free : 0;
1505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( pure_vtx_size )
1507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                elem_mat = Mat(1, graph->elem_size, CV_8U, &elem_buf[0]);
1509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvtest::randUni( rng, elem_mat, cvScalarAll(0), cvScalarAll(255) );
1510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            vtx = (CvGraphVtx*)&elem_buf[0];
1513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            idx0 = cvTsSimpleGraphAddVertex( sgraph, vtx + 1 );
1514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pass_data = cvtest::randInt(rng) % 2;
1516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            idx = cvGraphAddVtx( graph, pass_data ? vtx : 0, &vtx2 );
1517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( !pass_data && pure_vtx_size > 0 )
1519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                memcpy( vtx2 + 1, vtx + 1, pure_vtx_size );
1520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            vtx3 = cvGetGraphVtx( graph, idx );
1522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( (CV_IS_SET_ELEM(vtx3) && vtx3->flags == idx &&
1524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                        vtx3->first == 0) || (idx == idx0 && vtx3 == vtx2 &&
1525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                              (!pass_data || pure_vtx_size == 0 ||
1526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                               memcmp(vtx3 + 1, vtx + 1, pure_vtx_size) == 0)),
1527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The added element is not correct" );
1528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( (!first_free || first_free == (CvSetElem*)vtx3) &&
1530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (!next_free || graph->free_elems == next_free) &&
1531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      graph->active_count == prev_vtx_count + 1,
1532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The free node list is modified incorrectly" );
1533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else if( op == 1 ) // remove vertex
1535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            idx = cvtest::randInt(rng) % sgraph->vtx->max_count;
1537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( sgraph->vtx->free_count == sgraph->vtx->max_count || idx >= sgraph->vtx->count )
1538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                continue;
1539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            vtx_data = cvTsSimpleGraphFindVertex(sgraph, idx);
1541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( vtx_data == 0 )
1542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                continue;
1543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            vtx_degree0 = cvTsSimpleGraphVertexDegree( sgraph, idx );
1545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            first_free = graph->free_elems;
1546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            vtx = cvGetGraphVtx( graph, idx );
1548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( CV_IS_SET_ELEM(vtx) && vtx->flags == idx &&
1549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (pure_vtx_size == 0 || memcmp( vtx + 1, vtx_data, pure_vtx_size) == 0),
1550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "cvGetGraphVtx returned wrong element" );
1551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( cvtest::randInt(rng) % 2 )
1553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 vtx_degree = cvGraphVtxDegreeByPtr( graph, vtx );
1555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 cvGraphRemoveVtxByPtr( graph, vtx );
1556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
1558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 vtx_degree = cvGraphVtxDegree( graph, idx );
1560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 cvGraphRemoveVtx( graph, idx );
1561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cvTsSimpleGraphRemoveVertex( sgraph, idx );
1564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( vtx_degree == vtx_degree0,
1566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "Number of incident edges is different in two graph representations" );
1567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( !CV_IS_SET_ELEM(vtx) && !cvGetGraphVtx(graph, idx) &&
1569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (vtx->flags & CV_SET_ELEM_IDX_MASK) == idx,
1570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "cvGraphRemoveVtx[ByPtr] didn't release the vertex properly" );
1571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( graph->edges->active_count == prev_edge_count - vtx_degree,
1573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "cvGraphRemoveVtx[ByPtr] didn't remove all the incident edges "
1574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "(or removed some extra)" );
1575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( ((CvSetElem*)vtx)->next_free == first_free &&
1577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      graph->free_elems == (CvSetElem*)vtx &&
1578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      graph->active_count == prev_vtx_count - 1,
1579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The free node list has not been updated properly" );
1580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else if( op == 2 ) // add edge
1582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int v_idx[2] = {0,0}, res = 0;
1584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int v_prev_degree[2] = {0,0}, v_degree[2] = {0,0};
1585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( sgraph->vtx->free_count >= sgraph->vtx->max_count-1 )
1587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                continue;
1588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( i = 0, k = 0; i < 10; i++ )
1590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int j = cvtest::randInt(rng) % sgraph->vtx->count;
1592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                vtx_data = cvTsSimpleGraphFindVertex( sgraph, j );
1593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( vtx_data )
1594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
1595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    v_idx[k] = j;
1596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( k == 0 )
1597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        k++;
1598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    else if( v_idx[0] != v_idx[1] &&
1599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            cvTsSimpleGraphFindEdge( sgraph, v_idx[0], v_idx[1] ) == 0 )
1600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
1601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        k++;
1602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
1603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
1604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( k < 2 )
1608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                continue;
1609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            first_free = graph->edges->free_elems;
1611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            next_free = first_free ? first_free->next_free : 0;
1612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            edge = cvFindGraphEdge( graph, v_idx[0], v_idx[1] );
1614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( edge == 0, "Extra edge appeared in the graph" );
1615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( pure_edge_size > 0 )
1617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                elem_mat = Mat(1, graph->edges->elem_size, CV_8U, &elem_buf[0]);
1619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvtest::randUni( rng, elem_mat, cvScalarAll(0), cvScalarAll(255) );
1620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            edge = (CvGraphEdge*)&elem_buf[0];
1622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            // assign some default weight that is easy to check for
1624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            // consistensy, 'cause an edge weight is not stored
1625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            // in the simple graph
1626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            edge->weight = (float)(v_idx[0] + v_idx[1]);
1627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pass_data = cvtest::randInt(rng) % 2;
1628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            vtx = cvGetGraphVtx( graph, v_idx[0] );
1630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            vtx2 = cvGetGraphVtx( graph, v_idx[1] );
1631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( vtx != 0 && vtx2 != 0 && vtx->flags == v_idx[0] &&
1632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      vtx2->flags == v_idx[1], "Some of the vertices are missing" );
1633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( cvtest::randInt(rng) % 2 )
1635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_prev_degree[0] = cvGraphVtxDegreeByPtr( graph, vtx );
1637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_prev_degree[1] = cvGraphVtxDegreeByPtr( graph, vtx2 );
1638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 res = cvGraphAddEdgeByPtr(graph, vtx, vtx2, pass_data ? edge : 0, &edge2);
1639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_degree[0] = cvGraphVtxDegreeByPtr( graph, vtx );
1640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_degree[1] = cvGraphVtxDegreeByPtr( graph, vtx2 );
1641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
1643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_prev_degree[0] = cvGraphVtxDegree( graph, v_idx[0] );
1645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_prev_degree[1] = cvGraphVtxDegree( graph, v_idx[1] );
1646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 res = cvGraphAddEdge(graph, v_idx[0], v_idx[1], pass_data ? edge : 0, &edge2);
1647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_degree[0] = cvGraphVtxDegree( graph, v_idx[0] );
1648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_degree[1] = cvGraphVtxDegree( graph, v_idx[1] );
1649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            //edge3 = (CvGraphEdge*)cvGetSetElem( graph->edges, idx );
1652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( res == 1 && edge2 != 0 && CV_IS_SET_ELEM(edge2) &&
1653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      ((edge2->vtx[0] == vtx && edge2->vtx[1] == vtx2) ||
1654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                       (!CV_IS_GRAPH_ORIENTED(graph) && edge2->vtx[0] == vtx2 && edge2->vtx[1] == vtx)) &&
1655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (!pass_data || pure_edge_size == 0 || memcmp( edge2 + 1, edge + 1, pure_edge_size ) == 0),
1656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The edge has been added incorrectly" );
1657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( !pass_data )
1659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( pure_edge_size > 0 )
1661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    memcpy( edge2 + 1, edge + 1, pure_edge_size );
1662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                edge2->weight = edge->weight;
1663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( v_degree[0] == v_prev_degree[0] + 1 &&
1666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      v_degree[1] == v_prev_degree[1] + 1,
1667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The vertices lists have not been updated properly" );
1668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cvTsSimpleGraphAddEdge( sgraph, v_idx[0], v_idx[1], edge + 1 );
1670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( (!first_free || first_free == (CvSetElem*)edge2) &&
1672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (!next_free || graph->edges->free_elems == next_free) &&
1673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      graph->edges->active_count == prev_edge_count + 1,
1674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The free node list is modified incorrectly" );
1675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else if( op == 3 ) // find & remove edge
1677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int v_idx[2] = {0,0}, by_ptr;
1679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int v_prev_degree[2] = {0,0}, v_degree[2] = {0,0};
1680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( sgraph->vtx->free_count >= sgraph->vtx->max_count-1 )
1682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                continue;
1683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            edge_data = 0;
1685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( i = 0, k = 0; i < 10; i++ )
1686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int j = cvtest::randInt(rng) % sgraph->vtx->count;
1688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                vtx_data = cvTsSimpleGraphFindVertex( sgraph, j );
1689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if( vtx_data )
1690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
1691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    v_idx[k] = j;
1692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( k == 0 )
1693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        k++;
1694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    else
1695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
1696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        edge_data = cvTsSimpleGraphFindEdge( sgraph, v_idx[0], v_idx[1] );
1697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        if( edge_data )
1698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        {
1699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            k++;
1700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
1701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        }
1702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
1703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( k < 2 )
1707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                continue;
1708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            by_ptr = cvtest::randInt(rng) % 2;
1710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            first_free = graph->edges->free_elems;
1711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            vtx = cvGetGraphVtx( graph, v_idx[0] );
1713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            vtx2 = cvGetGraphVtx( graph, v_idx[1] );
1714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( vtx != 0 && vtx2 != 0 && vtx->flags == v_idx[0] &&
1715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      vtx2->flags == v_idx[1], "Some of the vertices are missing" );
1716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( by_ptr )
1718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 edge = cvFindGraphEdgeByPtr( graph, vtx, vtx2 );
1720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_prev_degree[0] = cvGraphVtxDegreeByPtr( graph, vtx );
1721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_prev_degree[1] = cvGraphVtxDegreeByPtr( graph, vtx2 );
1722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
1724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 edge = cvFindGraphEdge( graph, v_idx[0], v_idx[1] );
1726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_prev_degree[0] = cvGraphVtxDegree( graph, v_idx[0] );
1727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_prev_degree[1] = cvGraphVtxDegree( graph, v_idx[1] );
1728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            idx = edge->flags;
1731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( edge != 0 && edge->weight == v_idx[0] + v_idx[1] &&
1733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      ((edge->vtx[0] == vtx && edge->vtx[1] == vtx2) ||
1734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                       (!CV_IS_GRAPH_ORIENTED(graph) && edge->vtx[1] == vtx && edge->vtx[0] == vtx2)) &&
1735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      (pure_edge_size == 0 || memcmp(edge + 1, edge_data, pure_edge_size) == 0),
1736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "An edge is missing or incorrect" );
1737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( by_ptr )
1739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 cvGraphRemoveEdgeByPtr( graph, vtx, vtx2 );
1741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 edge2 = cvFindGraphEdgeByPtr( graph, vtx, vtx2 );
1742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_degree[0] = cvGraphVtxDegreeByPtr( graph, vtx );
1743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_degree[1] = cvGraphVtxDegreeByPtr( graph, vtx2 );
1744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
1746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 cvGraphRemoveEdge(graph, v_idx[0], v_idx[1] );
1748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 edge2 = cvFindGraphEdge( graph, v_idx[0], v_idx[1] );
1749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_degree[0] = cvGraphVtxDegree( graph, v_idx[0] );
1750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 v_degree[1] = cvGraphVtxDegree( graph, v_idx[1] );
1751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( !edge2 && !CV_IS_SET_ELEM(edge),
1754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The edge has not been removed from the edge set" );
1755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( v_degree[0] == v_prev_degree[0] - 1 &&
1757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      v_degree[1] == v_prev_degree[1] - 1,
1758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The vertices lists have not been updated properly" );
1759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cvTsSimpleGraphRemoveEdge( sgraph, v_idx[0], v_idx[1] );
1761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            CV_TS_SEQ_CHECK_CONDITION( graph->edges->free_elems == (CvSetElem*)edge &&
1763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      graph->edges->free_elems->next_free == first_free &&
1764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      graph->edges->active_count == prev_edge_count - 1,
1765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      "The free edge list has not been modified properly" );
1766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        //max_active_count = MAX( max_active_count, graph->active_count );
1769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        //mean_active_count += graph->active_count;
1770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_TS_SEQ_CHECK_CONDITION( graph->active_count == sgraph->vtx->max_count - sgraph->vtx->free_count &&
1772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                  graph->total >= graph->active_count &&
1773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                  (graph->total == 0 || graph->total >= prev_vtx_total),
1774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                  "The total number of graph vertices is not correct" );
1775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CV_TS_SEQ_CHECK_CONDITION( graph->edges->total >= graph->edges->active_count &&
1777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                  (graph->edges->total == 0 || graph->edges->total >= prev_edge_total),
1778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                  "The total number of graph vertices is not correct" );
1779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // CvGraph and simple graph do not necessary have the same "total" (active & free) number,
1781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        // so pass "graph->total" (or "graph->edges->total") to skip that check
1782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        test_seq_block_consistence( struct_idx, (CvSeq*)graph, graph->total );
1783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        test_seq_block_consistence( struct_idx, (CvSeq*)graph->edges, graph->edges->total );
1784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        update_progressbar();
1785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
1788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_GraphTest::run( int )
1792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    try
1794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        RNG& rng = ts->get_rng();
1796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int i, k;
1797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double t;
1798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        clear();
1800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        test_progress = -1;
1801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        simple_struct.resize(struct_count, 0);
1803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cxcore_struct.resize(struct_count, 0);
1804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( gen = 0; gen < generations; gen++ )
1806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            struct_idx = iter = -1;
1808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size) + min_log_storage_block_size;
1809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int block_size = cvRound( exp(t * CV_LOG2) );
1810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            block_size = MAX(block_size, (int)(sizeof(CvGraph) + sizeof(CvMemBlock) + sizeof(CvSeqBlock)));
1811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            storage.reset(cvCreateMemStorage(block_size));
1813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( i = 0; i < struct_count; i++ )
1815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int pure_elem_size[2], elem_size[2];
1817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int is_oriented = (gen + i) % 2;
1818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                for( k = 0; k < 2; k++ )
1819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
1820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    t = cvtest::randReal(rng)*(max_log_elem_size - min_log_elem_size) + min_log_elem_size;
1821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    int pe = cvRound( exp(t * CV_LOG2) ) - 1; // pure_elem_size==0 does also make sense
1822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    int delta = k == 0 ? sizeof(CvGraphVtx) : sizeof(CvGraphEdge);
1823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    int e = pe + delta;
1824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    e = (e + sizeof(size_t) - 1) & ~(sizeof(size_t)-1);
1825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    e = MIN( e, (int)(storage->block_size - sizeof(CvMemBlock) -
1826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                      sizeof(CvSeqBlock) - sizeof(void*)) );
1827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    pe = MIN(pe, e - delta);
1828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    pure_elem_size[k] = pe;
1829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    elem_size[k] = e;
1830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvTsReleaseSimpleGraph( (CvTsSimpleGraph**)&simple_struct[i] );
1833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                simple_struct[i] = cvTsCreateSimpleGraph( max_struct_size/4, pure_elem_size[0],
1834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                         pure_elem_size[1], is_oriented );
1835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cxcore_struct[i] = cvCreateGraph( is_oriented ? CV_ORIENTED_GRAPH : CV_GRAPH,
1836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                          sizeof(CvGraph), elem_size[0], elem_size[1],
1837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                          storage );
1838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( test_graph_ops( iterations*10 ) < 0 )
1841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return;
1842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            storage.release();
1844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    catch(int)
1847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//////////// graph scan test //////////////
1853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerclass Core_GraphScanTest : public Core_DynStructBaseTest
1855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerpublic:
1857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    Core_GraphScanTest();
1858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    void run( int );
1859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerprotected:
1861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    //int test_seq_block_consistence( int struct_idx );
1862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int create_random_graph( int );
1863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
1864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1866793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerCore_GraphScanTest::Core_GraphScanTest()
1867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    iterations = 100;
1869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct_count = 1;
1870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint Core_GraphScanTest::create_random_graph( int _struct_idx )
1874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    RNG& rng = ts->get_rng();
1876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int is_oriented = cvtest::randInt(rng) % 2;
1877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i, vtx_count = cvtest::randInt(rng) % max_struct_size;
1878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int edge_count = cvtest::randInt(rng) % MAX(vtx_count*20, 1);
1879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvGraph* graph;
1880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    struct_idx = _struct_idx;
1882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cxcore_struct[_struct_idx] = graph =
1883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cvCreateGraph(is_oriented ? CV_ORIENTED_GRAPH : CV_GRAPH,
1884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                      sizeof(CvGraph), sizeof(CvGraphVtx),
1885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                      sizeof(CvGraphEdge), storage );
1886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < vtx_count; i++ )
1888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler         cvGraphAddVtx( graph );
1889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( graph->active_count == vtx_count );
1891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i = 0; i < edge_count; i++ )
1893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int j = cvtest::randInt(rng) % vtx_count;
1895793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int k = cvtest::randInt(rng) % vtx_count;
1896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( j != k )
1898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             cvGraphAddEdge( graph, j, k );
1899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert( graph->active_count == vtx_count && graph->edges->active_count <= edge_count );
1902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 0;
1904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid Core_GraphScanTest::run( int )
1908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CvGraphScanner* scanner = 0;
1910793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    try
1911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        RNG& rng = ts->get_rng();
1913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        vector<uchar> vtx_mask, edge_mask;
1914793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        double t;
1915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int i;
1916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        clear();
1918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        test_progress = -1;
1919793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cxcore_struct.resize(struct_count, 0);
1921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1922793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( gen = 0; gen < generations; gen++ )
1923793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1924793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            struct_idx = iter = -1;
1925793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            t = cvtest::randReal(rng)*(max_log_storage_block_size - min_log_storage_block_size) + min_log_storage_block_size;
1926793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int storage_blocksize = cvRound( exp(t * CV_LOG2) );
1927793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            storage_blocksize = MAX(storage_blocksize, (int)(sizeof(CvGraph) + sizeof(CvMemBlock) + sizeof(CvSeqBlock)));
1928793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            storage_blocksize = MAX(storage_blocksize, (int)(sizeof(CvGraphEdge) + sizeof(CvMemBlock) + sizeof(CvSeqBlock)));
1929793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            storage_blocksize = MAX(storage_blocksize, (int)(sizeof(CvGraphVtx) + sizeof(CvMemBlock) + sizeof(CvSeqBlock)));
1930793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            storage.reset(cvCreateMemStorage(storage_blocksize));
1931793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1932793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( gen == 0 )
1933793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1934793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                // special regression test for one sample graph.
1935793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                // !!! ATTENTION !!! The test relies on the particular order of the inserted edges
1936793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                // (LIFO: the edge inserted last goes first in the list of incident edges).
1937793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                // if it is changed, the test will have to be modified.
1938793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1939793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int vtx_count = -1, edge_count = 0, edges[][3] =
1940793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
1941793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {0,4,'f'}, {0,1,'t'}, {1,4,'t'}, {1,2,'t'}, {2,3,'t'}, {4,3,'c'}, {3,1,'b'},
1942793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {5,7,'t'}, {7,5,'b'}, {5,6,'t'}, {6,0,'c'}, {7,6,'c'}, {6,4,'c'}, {-1,-1,0}
1943793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                };
1944793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1945793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CvGraph* graph = cvCreateGraph( CV_ORIENTED_GRAPH, sizeof(CvGraph),
1946793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                               sizeof(CvGraphVtx), sizeof(CvGraphEdge), storage );
1947793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1948793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                for( i = 0; edges[i][0] >= 0; i++ )
1949793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
1950793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    vtx_count = MAX( vtx_count, edges[i][0] );
1951793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    vtx_count = MAX( vtx_count, edges[i][1] );
1952793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1953793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                vtx_count++;
1954793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1955793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                for( i = 0; i < vtx_count; i++ )
1956793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     cvGraphAddVtx( graph );
1957793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1958793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                for( i = 0; edges[i][0] >= 0; i++ )
1959793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
1960793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CvGraphEdge* edge;
1961793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     cvGraphAddEdge( graph, edges[i][0], edges[i][1], 0, &edge );
1962793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    edge->weight = (float)edges[i][2];
1963793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1964793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1965793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                edge_count = i;
1966793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                scanner = cvCreateGraphScanner( graph, 0, CV_GRAPH_ALL_ITEMS );
1967793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1968793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                for(;;)
1969793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
1970793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    int code, a = -1, b = -1;
1971793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    const char* event = "";
1972793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     code = cvNextGraphItem( scanner );
1973793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1974793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    switch( code )
1975793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
1976793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case CV_GRAPH_VERTEX:
1977793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            event = "Vertex";
1978793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            vtx_count--;
1979793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            a = cvGraphVtxIdx( graph, scanner->vtx );
1980793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
1981793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case CV_GRAPH_TREE_EDGE:
1982793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            event = "Tree Edge";
1983793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            edge_count--;
1984793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            CV_TS_SEQ_CHECK_CONDITION( scanner->edge->weight == (float)'t',
1985793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                      "Invalid edge type" );
1986793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            a = cvGraphVtxIdx( graph, scanner->vtx );
1987793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            b = cvGraphVtxIdx( graph, scanner->dst );
1988793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
1989793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case CV_GRAPH_BACK_EDGE:
1990793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            event = "Back Edge";
1991793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            edge_count--;
1992793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            CV_TS_SEQ_CHECK_CONDITION( scanner->edge->weight == (float)'b',
1993793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                      "Invalid edge type" );
1994793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            a = cvGraphVtxIdx( graph, scanner->vtx );
1995793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            b = cvGraphVtxIdx( graph, scanner->dst );
1996793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
1997793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case CV_GRAPH_CROSS_EDGE:
1998793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            event = "Cross Edge";
1999793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            edge_count--;
2000793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            CV_TS_SEQ_CHECK_CONDITION( scanner->edge->weight == (float)'c',
2001793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                      "Invalid edge type" );
2002793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            a = cvGraphVtxIdx( graph, scanner->vtx );
2003793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            b = cvGraphVtxIdx( graph, scanner->dst );
2004793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2005793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case CV_GRAPH_FORWARD_EDGE:
2006793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            event = "Forward Edge";
2007793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            edge_count--;
2008793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            CV_TS_SEQ_CHECK_CONDITION( scanner->edge->weight == (float)'f',
2009793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                      "Invalid edge type" );
2010793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            a = cvGraphVtxIdx( graph, scanner->vtx );
2011793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            b = cvGraphVtxIdx( graph, scanner->dst );
2012793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2013793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case CV_GRAPH_BACKTRACKING:
2014793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            event = "Backtracking";
2015793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            a = cvGraphVtxIdx( graph, scanner->vtx );
2016793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2017793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case CV_GRAPH_NEW_TREE:
2018793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            event = "New search tree";
2019793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2020793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case CV_GRAPH_OVER:
2021793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            event = "End of procedure";
2022793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2023793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        default:
2024793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            CV_TS_SEQ_CHECK_CONDITION( 0, "Invalid code appeared during graph scan" );
2025793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
2026793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2027793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    ts->printf( cvtest::TS::LOG, "%s", event );
2028793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( a >= 0 )
2029793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
2030793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        if( b >= 0 )
2031793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            ts->printf( cvtest::TS::LOG, ": (%d,%d)", a, b );
2032793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        else
2033793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            ts->printf( cvtest::TS::LOG, ": %d", a );
2034793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
2035793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2036793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    ts->printf( cvtest::TS::LOG, "\n" );
2037793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2038793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if( code < 0 )
2039793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
2040793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
2041793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2042793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CV_TS_SEQ_CHECK_CONDITION( vtx_count == 0 && edge_count == 0,
2043793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                          "Not every vertex/edge has been visited" );
2044793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                update_progressbar();
2045793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2046793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2047793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            // for a random graph the test just checks that every graph vertex and
2048793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            // every edge is vitisted during the scan
2049793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for( iter = 0; iter < iterations; iter++ )
2050793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
2051793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                create_random_graph(0);
2052793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                CvGraph* graph = (CvGraph*)cxcore_struct[0];
2053793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2054793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                // iterate twice to check that scanner doesn't damage the graph
2055793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                for( i = 0; i < 2; i++ )
2056793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
2057793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CvGraphVtx* start_vtx = cvtest::randInt(rng) % 2 || graph->active_count == 0 ? 0 :
2058793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvGetGraphVtx( graph, cvtest::randInt(rng) % graph->active_count );
2059793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2060793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    scanner = cvCreateGraphScanner( graph, start_vtx, CV_GRAPH_ALL_ITEMS );
2061793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2062793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    vtx_mask.resize(0);
2063793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    vtx_mask.resize(graph->active_count, 0);
2064793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    edge_mask.resize(0);
2065793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    edge_mask.resize(graph->edges->active_count, 0);
2066793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2067793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    for(;;)
2068793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
2069793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        int code = cvNextGraphItem( scanner );
2070793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2071793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        if( code == CV_GRAPH_OVER )
2072793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2073793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        else if( code & CV_GRAPH_ANY_EDGE )
2074793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        {
2075793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            int edge_idx = scanner->edge->flags & CV_SET_ELEM_IDX_MASK;
2076793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2077793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            CV_TS_SEQ_CHECK_CONDITION( edge_idx < graph->edges->active_count &&
2078793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                      edge_mask[edge_idx] == 0,
2079793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                      "The edge is not found or visited for the second time" );
2080793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            edge_mask[edge_idx] = 1;
2081793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        }
2082793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        else if( code & CV_GRAPH_VERTEX )
2083793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        {
2084793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            int vtx_idx = scanner->vtx->flags & CV_SET_ELEM_IDX_MASK;
2085793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2086793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            CV_TS_SEQ_CHECK_CONDITION( vtx_idx < graph->active_count &&
2087793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                      vtx_mask[vtx_idx] == 0,
2088793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                                      "The vtx is not found or visited for the second time" );
2089793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            vtx_mask[vtx_idx] = 1;
2090793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        }
2091793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
2092793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2093793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cvReleaseGraphScanner( &scanner );
2094793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2095793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    CV_TS_SEQ_CHECK_CONDITION( cvtest::norm(Mat(vtx_mask),CV_L1) == graph->active_count &&
2096793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              cvtest::norm(Mat(edge_mask),CV_L1) == graph->edges->active_count,
2097793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                              "Some vertices or edges have not been visited" );
2098793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    update_progressbar();
2099793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
2100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cvClearMemStorage( storage );
2101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            storage.release();
2104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
2105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    catch(int)
2107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
2108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cvReleaseGraphScanner( &scanner );
2111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2114793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTEST(Core_DS_Seq, basic_operations) { Core_SeqBaseTest test; test.safe_run(); }
2115793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTEST(Core_DS_Seq, sort_invert) { Core_SeqSortInvTest test; test.safe_run(); }
2116793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTEST(Core_DS_Set, basic_operations) { Core_SetTest test; test.safe_run(); }
2117793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTEST(Core_DS_Graph, basic_operations) { Core_GraphTest test; test.safe_run(); }
2118793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTEST(Core_DS_Graph, scan) { Core_GraphScanTest test; test.safe_run(); }
2119