1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 #include "row_by_row.h"
27
28 #include <klib/log.h>
29 #include <klib/out.h>
30 #include <klib/num-gen.h>
31 #include <vdb/cursor.h>
32 #include <klib/progressbar.h>
33
34 #include "coldefs.h"
35 #include "cmn.h"
36
37 #include <sysalloc.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 rc_t Quitting( void ); /* because we cannot include <kapp/main.h> where it is defined! */
42
rbr_diff_columns_iter(const col_defs * defs,const VCursor * cur_1,const VCursor * cur_2,const struct diff_ctx * dctx,const struct num_gen_iter * iter,unsigned long int * diffs)43 static rc_t rbr_diff_columns_iter( const col_defs * defs, const VCursor * cur_1, const VCursor * cur_2,
44 const struct diff_ctx * dctx, const struct num_gen_iter * iter,
45 unsigned long int *diffs )
46 {
47 uint32_t column_count;
48 rc_t rc = col_defs_count( defs, &column_count );
49 if ( rc != 0 )
50 {
51 LOGERR ( klogInt, rc, "col_defs_count() failed" );
52 }
53 else
54 {
55 struct progressbar * progress = NULL;
56 int64_t row_id;
57 uint64_t rows_checked = 0;
58 uint64_t rows_different = 0;
59
60 if ( dctx -> show_progress )
61 make_progressbar( &progress, 2 );
62
63 while ( rc == 0 && num_gen_iterator_next( iter, &row_id, &rc ) && *diffs < dctx->max_err )
64 {
65 if ( rc == 0 ) rc = Quitting(); /* to be able to cancel the loop by signal */
66 if ( rc == 0 )
67 {
68 bool row_equal = true;
69
70 uint32_t col_id;
71 for ( col_id = 0; col_id < column_count && rc == 0; ++col_id )
72 {
73 col_pair * pair = VectorGet( &( defs -> cols ), col_id );
74 if ( pair != NULL )
75 {
76 bool col_equal;
77 rc = cmn_diff_column( pair, cur_1, cur_2, row_id, &col_equal );
78 if ( !col_equal )
79 {
80 row_equal = false;
81 ( *diffs )++;
82 }
83 }
84 } /* for ( col_id ... ) */
85
86 if ( !row_equal )
87 {
88 if ( rc == 0 ) rc = KOutMsg( "\n" );
89 rows_different++;
90 }
91 rows_checked ++;
92
93 if ( progress != NULL )
94 {
95 uint32_t progress_value;
96 if ( num_gen_iterator_percent( iter, 2, &progress_value ) == 0 )
97 update_progressbar( progress, progress_value );
98 }
99
100 } /* if (!Quitting) */
101 } /* while ( num_gen_iterator_next() ) */
102
103 if ( rc == 0 )
104 rc = KOutMsg( "\n%,lu rows checked ( %d columns each ), %,lu rows differ\n",
105 rows_checked, column_count, rows_different );
106
107 if ( progress != NULL )
108 destroy_progressbar( progress );
109
110 } /* if ( col_defs_count == 0 )*/
111
112 return rc;
113 }
114
115
rbr_diff_columns(col_defs * defs,const VTable * tab_1,const VTable * tab_2,const struct diff_ctx * dctx,unsigned long int * diffs)116 rc_t rbr_diff_columns( col_defs * defs, const VTable * tab_1, const VTable * tab_2,
117 const struct diff_ctx * dctx, unsigned long int *diffs )
118 {
119 const VCursor * cur_1;
120 rc_t rc = VTableCreateCursorRead( tab_1, &cur_1 );
121 if ( rc != 0 )
122 {
123 LOGERR ( klogInt, rc, "VTableCreateCursorRead( acc #1 ) failed" );
124 }
125 else
126 {
127 const VCursor * cur_2;
128 rc = VTableCreateCursorRead( tab_2, &cur_2 );
129 if ( rc != 0 )
130 {
131 LOGERR ( klogInt, rc, "VTableCreateCursorRead( acc #2 ) failed" );
132 }
133 else
134 {
135 rc = col_defs_add_to_cursor( defs, cur_1, 0 );
136 if ( rc != 0 )
137 {
138 LOGERR ( klogInt, rc, "failed to add all requested columns to cursor of 1st accession" );
139 }
140 else
141 {
142 rc = col_defs_add_to_cursor( defs, cur_2, 1 );
143 if ( rc != 0 )
144 {
145 LOGERR ( klogInt, rc, "failed to add all requested columns to cursor of 2nd accession" );
146 }
147 else
148 {
149 rc = VCursorOpen( cur_1 );
150 if ( rc != 0 )
151 {
152 LOGERR ( klogInt, rc, "VCursorOpen( acc #1 ) failed" );
153 }
154 else
155 {
156 rc = VCursorOpen( cur_2 );
157 if ( rc != 0 )
158 {
159 LOGERR ( klogInt, rc, "VCursorOpen( acc #2 ) failed" );
160 }
161 else
162 {
163 struct num_gen * rows_to_diff = NULL;
164 rc = cmn_make_num_gen( cur_1, cur_2, 0, 0, dctx -> rows, &rows_to_diff );
165 if ( rc == 0 && rows_to_diff != NULL )
166 {
167 const struct num_gen_iter * iter = NULL;
168 rc = num_gen_iterator_make( rows_to_diff, &iter );
169 if ( rc != 0 )
170 {
171 LOGERR ( klogInt, rc, "num_gen_iterator_make() failed" );
172 }
173 else if ( iter != NULL )
174 {
175 /* *************************************************************** */
176 rc = rbr_diff_columns_iter( defs, cur_1, cur_2, dctx, iter, diffs );
177 /* *************************************************************** */
178 num_gen_iterator_destroy( iter );
179 }
180 num_gen_destroy( rows_to_diff );
181 }
182 }
183 }
184 }
185 }
186 VCursorRelease( cur_2 );
187 }
188 VCursorRelease( cur_1 );
189 }
190 return rc;
191 }
192