// Проверяет, можно ли считать таблицей нечто с адресом p и шириной элементов N static bool slow_check_for_data_table (int N, byte *p, uint32 &type, BYTE *&table_start, BYTE *&table_end, byte *bufstart, byte *bufend, byte *buf, uint64 &offset, Buffer &ReorderingBuffer) { // Сначала сканируем назад, начиная с p, в поисках начала таблицы int useless; table_start = search_for_table_boundary (-N, p, bufstart, bufend, useless); // Затем сканируем вперёд, начиная с table_start, в поисках конца таблицы table_end = search_for_table_boundary (N, table_start, bufstart, bufend, useless); // +разрешить таблицы с широкими столбцами и небольшим числом строк (sqrt(N)*rows >= X) // +учитывать расстояние до предыдущей таблицы для оптимизации конечного уровня сжатия // улучшать оценку для столбцов с фиксированной разницей между элементами (типа 8,16,24,32...) // считать количество байтов, энтропия которых уменьшилась от вычитания [как минимум на два бита] // Теперь выясняем, достаточно ли хороша эта таблица для того, чтобы её стоило закодировать int rows = (table_end-table_start)/N; int useful = rows - useless; // количество полезных строк таблицы double skipBits = logb(mymax(table_start-bufstart,1)); // сколько бит придётся потратить на кодирование поля skip stat ((slow_checks++, verbose>1 && printf ("Slow check %08x-%08x (%d*%d+%d)\n", int(table_start-buf+offset), int(table_end-buf+offset), N, useful, useless))); if (useful*sqrt((double)N) > 30+4*skipBits) { stat ((table_count++, table_sumlen += N*rows, table_skipBits+=skipBits)); stat (verbose>0 && printf("%08x-%08x %d*%d ", int(table_start-buf+offset), int(table_end-buf+offset), N, rows)); // Определить какие столбцы нужно вычесть, а какие являются иммутабельными. // Вычесть вычитаемое и собрать иммутабельные столбцы в начале таблицы (для удобства работы lz77) bool doDiff[MAX_ELEMENT_SIZE], immutable[MAX_ELEMENT_SIZE]; analyze_table (N, table_start, rows, doDiff, immutable); diff_table (N, table_start, rows, doDiff); reorder_table (N, table_start, rows, immutable, ReorderingBuffer); type = encode_type (N, doDiff, immutable); stat (verbose>0 && printf("\n")); return TRUE; } return FALSE; }
Relation Relation::set_difference(string new_table_name, Relation other_table) { //Check if relations are union compatible if ((*this).union_compatible(other_table)) { //Create new relation to be returned at end of function; Relation diff_table(new_table_name, attr_names, attr_types, key_pos); for (int i = 0; i < table.size(); i++) { bool insert = true; for (int j = 0; j < other_table.table.size(); j++) { if (table[i] == other_table.table[j]) { insert = false; break; } } if (insert) { diff_table.insert_row(table[i]); } } //Return new relation created from difference return diff_table; } }
/* fast evaluation of basis functions */ void Spline::basis_funcs(double x, Vec &b)const { diff_table(x, ordm1_); b[0] = 1.; for (int j = 1; j <= ordm1_; j++) { double saved = 0.; for (int r = 0; r < j; r++) { double term = b[r]/(rdel[r] + ldel[j - 1 - r]); b[r] = saved + rdel[r] * term; saved = ldel[j - 1 - r] * term; } b[j] = saved; } }
/* fast evaluation of basis functions */ static void basis_funcs(splPTR sp, double x, double *b) { int j, r; double saved, term; diff_table(sp, x, sp->ordm1); b[0] = 1.; for (j = 1; j <= sp->ordm1; j++) { saved = 0.; for (r = 0; r < j; r++) { term = b[r]/(sp->rdel[r] + sp->ldel[j - 1 - r]); b[r] = saved + sp->rdel[r] * term; saved = sp->ldel[j - 1 - r] * term; } b[j] = saved; } }
/* "slow" evaluation of (derivative of) basis functions */ static double evaluate(splPTR sp, double x, int nder) { register double *lpt, *rpt, *apt, *ti = sp->knots + sp->curs; int inner, outer = sp->ordm1; if (sp->boundary && nder == sp->ordm1) { /* value is arbitrary */ return 0.0; } while(nder--) { for(inner = outer, apt = sp->a, lpt = ti - outer; inner--; apt++, lpt++) *apt = outer * (*(apt + 1) - *apt)/(*(lpt + outer) - *lpt); outer--; } diff_table(sp, x, outer); while(outer--) for(apt = sp->a, lpt = sp->ldel + outer, rpt = sp->rdel, inner = outer + 1; inner--; lpt--, rpt++, apt++) *apt = (*(apt + 1) * *lpt + *apt * *rpt)/(*rpt + *lpt); return sp->a[0]; }
double Spline::evaluate_derivs(double x, int nder)const { register const double *lpt, *rpt, *ti = knots.data() + curs; register double *apt; int inner, outer = ordm1_; if (boundary && nder == ordm1_) { /* value is arbitrary */ return 0.0; } while(nder--) { for(inner = outer, apt = a.data(), lpt = ti - outer; inner--; apt++, lpt++) *apt = outer * (*(apt + 1) - *apt)/(*(lpt + outer) - *lpt); outer--; } diff_table(x, outer); while(outer--) for(apt = a.data(), lpt = ldel.data() + outer, rpt = rdel.data(), inner = outer + 1; inner--; lpt--, rpt++, apt++) *apt = (*(apt + 1) * *lpt + *apt * *rpt)/(*rpt + *lpt); return a[0]; }
/* fast evaluation of basis functions */ static void basis_funcs(splPTR sp, double x, double *b) { diff_table(sp, x, sp->ordm1); b[0] = 1.; for (int j = 1; j <= sp->ordm1; j++) { double saved = 0.; for (int r = 0; r < j; r++) { // do not divide by zero double den = sp->rdel[r] + sp->ldel[j - 1 - r]; if(den != 0) { double term = b[r]/den; b[r] = saved + sp->rdel[r] * term; saved = sp->ldel[j - 1 - r] * term; } else { if(r != 0 || sp->rdel[r] != 0.) b[r] = saved; saved = 0.; } } b[j] = saved; } }