11 #include "eckit/config/Resource.h"
12 #include "eckit/exception/Exceptions.h"
13 #include "eckit/filesystem/PathName.h"
24 #if __cplusplus >= 199711L
25 #define isnan(x) std::isnan(x)
29 using namespace eckit;
41 Comparator::Comparator(
bool checkMissingFlag)
43 checkMissingFlag_(checkMissingFlag),
44 NaN_isOK_(Resource<bool>(
"$odc_NAN_IS_OK", false))
50 std::vector<std::string> noExcludedColumnTypes;
51 std::vector<std::string> noExcludedColumns;
52 compare(
p1, p2, noExcludedColumnTypes, noExcludedColumns);
57 std::vector<std::string> noExcludedColumnTypes;
58 std::vector<std::string> noExcludedColumns;
67 compare(it1, end1, it2, end2,
"left",
"right", noExcludedColumnTypes, noExcludedColumns);
71 const std::vector<std::string>& excludedColumnsTypes,
72 const std::vector<std::string>& excludedColumns)
74 Tracer t(Log::debug(), std::string(
"Comparator::compare: ") +
p1 +
", " + p2);
84 compare(it1, end1, it2, end2,
p1, p2, excludedColumnsTypes, excludedColumns);
90 ss <<
"Values different in column " << column.
name() <<
": "
101 std::vector<int> skipColsUnused;
110 const std::vector<int>& skipCols) {
112 std::vector<int>::const_iterator nextSkipCol = skipCols.begin();
114 const double* pdata1 =
data1;
115 const double* pdata2 =
data2;
117 unsigned long long numberOfDifferences (0);
118 for (
int i=0;
i < nCols;
i++) {
121 if (nextSkipCol != skipCols.end() && (*nextSkipCol) ==
i) {
123 pdata1 += md1[
i]->dataSizeDoubles();
124 pdata2 += md2[
i]->dataSizeDoubles();
130 const Column& column2(*md2[
i]);
140 size_t len1 = ::strnlen(
reinterpret_cast<const char*
>(pdata1), width1);
141 size_t len2 = ::strnlen(
reinterpret_cast<const char*
>(pdata2), width2);
143 ::strncmp(
reinterpret_cast<const char*
>(pdata1),
reinterpret_cast<const char*
>(pdata2), len1)) {
145 std::ostringstream ss;
146 ss <<
"String values differ in column " << column.
name() <<
": "
147 << std::string(
reinterpret_cast<const char*
>(pdata1), len1) <<
" is not equal to "
148 << std::string(
reinterpret_cast<const char*
>(pdata2), len2) << std::endl;
156 if (! (
same(*pdata1, *pdata2) || (
NaN_isOK_ && (::isnan(*pdata1) && ::isnan(*pdata2)))))
160 if (! (
same(
float(*pdata1),
float(*pdata2)) || (
NaN_isOK_ && (::isnan(*pdata1) && ::isnan(*pdata2)))))
165 ASSERT(!
"Unknown type");
168 }
catch (Exception &e) {
169 ++numberOfDifferences;
170 Log::info() <<
"While comparing rows number " <<
nRow_ <<
", columns " <<
i
171 <<
" found different." << std::endl;
172 Log::info() <<
" " << e.what() << std::endl;
174 Log::info() <<
" data1[" <<
i <<
"] = " << std::scientific << *pdata1 << std::endl;
175 Log::info() <<
" data2[" <<
i <<
"] = " << std::scientific << *pdata2 << std::endl;
177 Log::info() <<
" md1[" <<
i <<
"] = " << *md1[
i] << std::endl;
178 Log::info() <<
" md2[" <<
i <<
"] = " << *md2[
i] << std::endl;
184 pdata1 += md1[
i]->dataSizeDoubles();
185 pdata2 += md2[
i]->dataSizeDoubles();
188 if (numberOfDifferences)
191 ss <<
"Files differ. ";
192 throw Exception(ss.str());
198 const std::set<std::string>& excludedColumnsTypes,
199 const std::set<std::string>& excludedColumns,
200 std::vector<int>& skipCols) {
202 ASSERT(
"Number of columns must be the same" && (metaData1.size() == metaData2.size()));
207 size_t size = metaData1.size();
208 for (
size_t i = 0;
i < size;
i++)
210 Column &column1 = *metaData1[
i];
211 Column &column2 = *metaData2[
i];
214 ASSERT(column1.
name() == column2.
name());
217 if (excludedColumns.find(column1.
name()) != excludedColumns.end()) {
218 skipCols.push_back(
i);
222 if (excludedColumnsTypes.find(column1.
name()) == excludedColumnsTypes.end())
224 ASSERT(column1.
type() == column2.
type());
229 Log::error() <<
"Comparator::compare: bitfield definitions for column "
230 <<
i <<
" '" << column1.
name() <<
"' differ." << std::endl;
239 Log::warning() << column1.
name() <<
" : "
240 <<
"column1.missingValue()=" << column1.
missingValue() <<
", "
241 <<
"column2.missingValue()=" << column2.
missingValue() <<
", "
250 Log::warning() << column1.
name() <<
" : "
251 <<
"column1.missingValue()=" << column1.
missingValue() <<
", "
252 <<
"column2.missingValue()=" << column2.
missingValue() <<
", "
260 Log::info() <<
"While comparing column " <<
i <<
": "
261 << column1.
name() << std::endl;
ValuesDifferent(const std::string &what)
bool compare(T1 &it1, const T1 &end1, T2 &it2, const T2 &end2, const std::string &desc1, const std::string &desc2)
void raiseNotEqual(const core::Column &, double, double)
static int same(double A, double B)
const iterator end() const
void bitfieldDef(const eckit::sql::BitfieldDef &b)
void hasMissing(bool h)
Delegations to Codec:
size_t dataSizeDoubles() const
void missingValue(double v)
void name(const std::string name)
static api::ColumnType type(const std::string &)