mirror of
https://github.com/Z3Prover/z3
synced 2025-04-10 19:27:06 +00:00
621 lines
22 KiB
C++
621 lines
22 KiB
C++
/*++
|
|
Copyright (c) 2010 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dl_skip_table.h
|
|
|
|
Abstract:
|
|
|
|
<abstract>
|
|
|
|
Author:
|
|
|
|
Nikolaj Bjorner (nbjorner)
|
|
Leonardo de Moura (leonardo) 2010-10-14
|
|
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#ifndef _EXTERNAL_RELEASE
|
|
|
|
#include "dl_skip_table.h"
|
|
#include "dl_table.h"
|
|
#include "dl_context.h"
|
|
|
|
|
|
namespace datalog {
|
|
|
|
skip_table & skip_table_plugin::get(table_base& r) {
|
|
return static_cast<skip_table&>(r);
|
|
}
|
|
|
|
skip_table const & skip_table_plugin::get(table_base const& r) {
|
|
return static_cast<skip_table const &>(r);
|
|
}
|
|
|
|
table_base * skip_table_plugin::mk_empty(const table_signature & s) {
|
|
return alloc(skip_table, *this, s);
|
|
}
|
|
|
|
skip_table* skip_table_plugin::mk_join(
|
|
table_base const& t1, table_base const& t2, table_signature const& result_sig,
|
|
unsigned_vector const& cols1, unsigned_vector const& cols2) {
|
|
skip_table const& s1 = get(t1);
|
|
skip_table const& s2 = get(t2);
|
|
imdd_manager& m = s1.get_imdd_manager();
|
|
imdd_ref pr(m);
|
|
m.mk_join(s1.get_imdd(), s2.get_imdd(), pr, cols1, cols2);
|
|
return alloc(skip_table, s1.get_plugin(), result_sig, pr);
|
|
}
|
|
|
|
skip_table* skip_table_plugin::mk_join_project(
|
|
table_base const& t1, table_base const& t2, table_signature const& result_sig,
|
|
unsigned_vector const& cols1, unsigned_vector const& cols2,
|
|
unsigned_vector const& proj_cols) {
|
|
|
|
skip_table const& s1 = get(t1);
|
|
skip_table const& s2 = get(t2);
|
|
imdd_manager& m = s1.get_imdd_manager();
|
|
imdd_ref pr(m);
|
|
m.mk_join_project(s1.get_imdd(), s2.get_imdd(), pr, cols1, cols2, proj_cols);
|
|
return alloc(skip_table, s1.get_plugin(), result_sig, pr);
|
|
}
|
|
|
|
class skip_table_plugin::join_fn : public convenient_table_join_fn {
|
|
public:
|
|
join_fn(const table_base & t1, const table_base & t2,
|
|
unsigned col_cnt, const unsigned * cols1, const unsigned * cols2):
|
|
convenient_table_join_fn(t1.get_signature(), t2.get_signature(), col_cnt, cols1, cols2) {
|
|
}
|
|
|
|
virtual table_base* operator()(const table_base & t1, const table_base & t2) {
|
|
return skip_table_plugin::mk_join(t1, t2, get_result_signature(), m_cols1, m_cols2);
|
|
}
|
|
};
|
|
|
|
table_join_fn * skip_table_plugin::mk_join_fn(const table_base & t1, const table_base & t2,
|
|
unsigned col_cnt, const unsigned * cols1, const unsigned * cols2) {
|
|
if (check_kind(t1) && check_kind(t2)) {
|
|
return alloc(join_fn, t1, t2, col_cnt, cols1, cols2);
|
|
}
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
class skip_table_plugin::join_project_fn : public convenient_table_join_project_fn {
|
|
public:
|
|
join_project_fn(const table_base & t1, const table_base & t2,
|
|
unsigned col_cnt, const unsigned * cols1, const unsigned * cols2,
|
|
unsigned removed_col_cnt, const unsigned * removed_cols):
|
|
convenient_table_join_project_fn(t1.get_signature(), t2.get_signature(), col_cnt, cols1, cols2,
|
|
removed_col_cnt, removed_cols) {
|
|
}
|
|
|
|
virtual table_base* operator()(const table_base & t1, const table_base & t2) {
|
|
return skip_table_plugin::mk_join_project(t1, t2, get_result_signature(), m_cols1, m_cols2, m_removed_cols);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
table_join_fn * skip_table_plugin::mk_join_project_fn(
|
|
const table_base & t1, const table_base & t2,
|
|
unsigned joined_col_cnt, const unsigned * cols1, const unsigned * cols2,
|
|
unsigned removed_col_cnt, const unsigned * removed_cols) {
|
|
if (check_kind(t1) && check_kind(t2)) {
|
|
return alloc(join_project_fn, t1, t2, joined_col_cnt, cols1, cols2, removed_col_cnt, removed_cols);
|
|
}
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
class skip_table_plugin::union_fn : public table_union_fn {
|
|
public:
|
|
virtual void operator()(table_base& tgt, const table_base& src, table_base* delta) {
|
|
skip_table& s1 = get(tgt);
|
|
skip_table const& s2 = get(src);
|
|
imdd_manager& m = s1.get_imdd_manager();
|
|
imdd_ref r(m);
|
|
m.mk_union(s1.get_imdd(), s2.get_imdd(), r);
|
|
if (delta) {
|
|
skip_table& d = get(*delta);
|
|
if (m.is_subset(r, s1.get_imdd())) {
|
|
d.update(m.mk_empty(s1.get_signature().size()));
|
|
}
|
|
else {
|
|
d.update(r);
|
|
}
|
|
}
|
|
s1.update(r);
|
|
}
|
|
};
|
|
|
|
table_union_fn * skip_table_plugin::mk_union_fn(const table_base & tgt, const table_base & src, const table_base * delta) {
|
|
if (check_kind(tgt) && check_kind(src) && (!delta || check_kind(*delta))) {
|
|
return alloc(union_fn);
|
|
}
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
skip_table* skip_table_plugin::mk_project(table_base const& src, table_signature const& result_sig, unsigned_vector const& cols) {
|
|
skip_table const& s = get(src);
|
|
imdd_manager& m = s.get_imdd_manager();
|
|
imdd_ref pr(m);
|
|
m.mk_project(s.get_imdd(), pr, cols.size(), cols.c_ptr());
|
|
return alloc(skip_table, s.get_plugin(), result_sig, pr);
|
|
}
|
|
|
|
|
|
class skip_table_plugin::project_fn : public convenient_table_project_fn {
|
|
public:
|
|
project_fn(table_signature const& orig_sig, unsigned col_cnt, unsigned const* removed_cols):
|
|
convenient_table_project_fn(orig_sig, col_cnt, removed_cols) {}
|
|
|
|
table_base* operator()(table_base const& src) {
|
|
return mk_project(src, get_result_signature(), m_removed_cols);
|
|
}
|
|
};
|
|
|
|
table_transformer_fn * skip_table_plugin::mk_project_fn(const table_base & t, unsigned col_cnt, const unsigned * removed_cols) {
|
|
if (check_kind(t)) {
|
|
return alloc(project_fn, t.get_signature(), col_cnt, removed_cols);
|
|
}
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
class skip_table_plugin::rename_fn : public convenient_table_rename_fn {
|
|
|
|
void swap2(imdd_ref& n, unsigned col1, unsigned col2) {
|
|
imdd_manager& m = n.get_manager();
|
|
imdd_ref tmp(m);
|
|
if (col1 == col2) {
|
|
return;
|
|
}
|
|
if (col1 > col2) {
|
|
std::swap(col1, col2);
|
|
}
|
|
for (unsigned i = col1; i < col2; ++i) {
|
|
m.mk_swap(n, tmp, i);
|
|
n = tmp;
|
|
}
|
|
for (unsigned i = col2 - 1; i > col1; ) {
|
|
--i;
|
|
m.mk_swap(n, tmp, i);
|
|
n = tmp;
|
|
}
|
|
}
|
|
public:
|
|
rename_fn(table_signature const& sig, unsigned cycle_len, unsigned const* cycle):
|
|
convenient_rename_fn(sig, cycle_len, cycle) {}
|
|
|
|
table_base* operator()(table_base const& src) {
|
|
TRACE("skip",
|
|
for (unsigned i = 0; i < m_cycle.size(); ++i) {
|
|
tout << m_cycle[i] << " ";
|
|
}
|
|
tout << "\n";
|
|
src.display(tout););
|
|
skip_table const& s = get(src);
|
|
imdd_ref n(s.m_imdd, s.get_imdd_manager());
|
|
unsigned cycle_len = m_cycle.size();
|
|
unsigned col1, col2;
|
|
// TBD: review this for proper direction
|
|
for (unsigned i = 0; i + 1 < cycle_len; ++i) {
|
|
col1 = m_cycle[i];
|
|
col2 = m_cycle[i+1];
|
|
swap2(n, col1, col2);
|
|
}
|
|
if (cycle_len > 2) {
|
|
col1 = m_cycle[cycle_len-1];
|
|
col2 = m_cycle[0];
|
|
swap2(n, col1, col2);
|
|
}
|
|
return alloc(skip_table, s.get_plugin(), get_result_signature(), n);
|
|
}
|
|
};
|
|
|
|
table_transformer_fn * skip_table_plugin::mk_rename_fn(const table_base & t, unsigned len, const unsigned * cycle) {
|
|
if (check_kind(t)) {
|
|
return alloc(rename_fn, t.get_signature(), len, cycle);
|
|
}
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
class skip_table_plugin::filter_identical_fn : public table_mutator_fn {
|
|
unsigned_vector m_cols;
|
|
|
|
public:
|
|
filter_identical_fn(unsigned cnt, unsigned const* cols):
|
|
m_cols(cnt, cols)
|
|
{}
|
|
|
|
void operator()(table_base & t) {
|
|
skip_table& s = get(t);
|
|
imdd_manager& m = s.get_imdd_manager();
|
|
m.mk_filter_identical(s.get_imdd(), s.m_imdd, m_cols.size(), m_cols.c_ptr(), true);
|
|
}
|
|
};
|
|
|
|
table_mutator_fn * skip_table_plugin::mk_filter_identical_fn(const table_base & t, unsigned col_cnt,
|
|
const unsigned * identical_cols) {
|
|
if (check_kind(t)) {
|
|
return alloc(filter_identical_fn, col_cnt, identical_cols);
|
|
}
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
class skip_table_plugin::filter_equal_fn : public table_mutator_fn {
|
|
unsigned m_col;
|
|
unsigned m_value;
|
|
public:
|
|
filter_equal_fn(const table_base & t, const table_element & v, unsigned col):
|
|
m_col(col),
|
|
m_value(static_cast<unsigned>(v))
|
|
{
|
|
SASSERT(v <= UINT_MAX);
|
|
}
|
|
|
|
virtual void operator()(table_base& src) {
|
|
skip_table& s = get(src);
|
|
imdd_manager& m = s.get_imdd_manager();
|
|
m.mk_filter_equal(s.get_imdd(), s.m_imdd, m_col, m_value);
|
|
}
|
|
};
|
|
|
|
table_mutator_fn * skip_table_plugin::mk_filter_equal_fn(const table_base & t, const table_element & value,
|
|
unsigned col) {
|
|
if (check_kind(t)) {
|
|
return alloc(filter_equal_fn, t, value, col);
|
|
}
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
class skip_table_plugin::filter_not_equal_fn : public table_mutator_fn {
|
|
unsigned m_col;
|
|
unsigned m_value;
|
|
public:
|
|
filter_not_equal_fn(const table_base & t, const table_element & v, unsigned col):
|
|
m_col(col),
|
|
m_value(static_cast<unsigned>(v))
|
|
{
|
|
SASSERT(v <= UINT_MAX);
|
|
}
|
|
|
|
virtual void operator()(table_base& src) {
|
|
skip_table& s = get(src);
|
|
imdd_manager& m = s.get_imdd_manager();
|
|
m.mk_filter_disequal(s.get_imdd(), s.m_imdd, m_col, m_value);
|
|
}
|
|
};
|
|
|
|
table_mutator_fn * skip_table_plugin::mk_filter_not_equal_fn(const table_base & t, const table_element & value,
|
|
unsigned col) {
|
|
if (check_kind(t)) {
|
|
return alloc(filter_not_equal_fn, t, value, col);
|
|
}
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
class skip_table_plugin::filter_distinct_fn : public table_mutator_fn {
|
|
unsigned m_col1;
|
|
unsigned m_col2;
|
|
public:
|
|
filter_distinct_fn(const table_base & t, unsigned col1, unsigned col2):
|
|
m_col1(col1),
|
|
m_col2(col2) {
|
|
}
|
|
|
|
virtual void operator()(table_base& src) {
|
|
skip_table& s = get(src);
|
|
imdd_manager& m = s.get_imdd_manager();
|
|
m.mk_filter_distinct(s.get_imdd(), s.m_imdd, m_col1, m_col2);
|
|
}
|
|
};
|
|
|
|
table_mutator_fn * skip_table_plugin::mk_filter_distinct_fn(const table_base & t, unsigned col1, unsigned col2) {
|
|
if (check_kind(t)) {
|
|
return alloc(filter_distinct_fn, t, col1, col2);
|
|
}
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// The default implementation uses an iterator
|
|
// if the condition is a comparison <, <=, then interval table native will be an advantage.
|
|
//
|
|
table_mutator_fn * skip_table_plugin::mk_filter_interpreted_fn(const table_base & t, app * condition) {
|
|
ast_manager& m = get_ast_manager();
|
|
dl_decl_util& util = get_context().get_decl_util();
|
|
uint64 value;
|
|
|
|
if (m.is_eq(condition)) {
|
|
expr* x = condition->get_arg(0);
|
|
expr* y = condition->get_arg(1);
|
|
if (is_var(y)) {
|
|
std::swap(x,y);
|
|
}
|
|
if (is_var(x) && is_var(y)) {
|
|
unsigned cols[2] = { to_var(x)->get_idx(), to_var(y)->get_idx() };
|
|
return mk_filter_identical_fn(t, 2, cols);
|
|
}
|
|
if (is_var(x) && util.is_numeral_ext(y, value)) {
|
|
return mk_filter_equal_fn(t, value, to_var(x)->get_idx());
|
|
}
|
|
}
|
|
|
|
if (m.is_not(condition) && is_app(condition->get_arg(0))) {
|
|
condition = to_app(condition->get_arg(0));
|
|
if (m.is_eq(condition)) {
|
|
expr* x = condition->get_arg(0);
|
|
expr* y = condition->get_arg(1);
|
|
if (is_var(y)) {
|
|
std::swap(x,y);
|
|
}
|
|
if (is_var(x) && is_var(y)) {
|
|
return mk_filter_distinct_fn(t, to_var(x)->get_idx(), to_var(y)->get_idx());
|
|
}
|
|
if (is_var(x) && util.is_numeral_ext(y, value)) {
|
|
return mk_filter_not_equal_fn(t, value, to_var(x)->get_idx());
|
|
}
|
|
}
|
|
}
|
|
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
class skip_table_plugin::filter_by_negation_fn : public convenient_table_negation_filter_fn {
|
|
public:
|
|
filter_by_negation_fn(
|
|
const table_base & tgt, const table_base & neg,
|
|
unsigned joined_col_cnt, const unsigned * t_cols, const unsigned * negated_cols)
|
|
: convenient_table_negation_filter_fn(tgt, neg, joined_col_cnt, t_cols, negated_cols) {
|
|
|
|
}
|
|
|
|
//
|
|
// Compute
|
|
// { (x,y) | t(x,y) & ! exists z . negated_obj(x,z) }
|
|
//
|
|
// 1. Project z
|
|
// 2. Join with result.
|
|
//
|
|
|
|
virtual void operator()(table_base & tgt0, const table_base & neg0) {
|
|
skip_table & tgt = get(tgt0);
|
|
const skip_table & neg = get(neg0);
|
|
unsigned_vector cols2(m_cols2);
|
|
unsigned_vector proj_cols;
|
|
table_base* t1 = 0;
|
|
if (!m_all_neg_bound) {
|
|
unsigned_vector proj_cols, remap;
|
|
table_signature sig2;
|
|
table_signature const& neg_sig = neg.get_signature();
|
|
for (unsigned i = 0, j = 0; i < m_bound.size(); ++i) {
|
|
if (m_bound[i]) {
|
|
remap.push_back(j++);
|
|
sig2.push_back(neg_sig[i]);
|
|
}
|
|
else {
|
|
proj_cols.push_back(i);
|
|
remap.push_back(0);
|
|
}
|
|
}
|
|
for (unsigned i = 0; i < cols2.size(); ++i) {
|
|
cols2[i] = remap[cols2[i]];
|
|
}
|
|
skip_table* t0 = skip_table_plugin::mk_project(neg, sig2, proj_cols);
|
|
t1 = t0->complement();
|
|
t0->deallocate();
|
|
proj_cols.reset();
|
|
}
|
|
else {
|
|
t1 = neg.complement();
|
|
}
|
|
for (unsigned i = 0; i < t1->get_signature().size(); ++i) {
|
|
proj_cols.push_back(tgt0.get_signature().size()+i);
|
|
}
|
|
skip_table* t2 = skip_table_plugin::mk_join_project(tgt0, *t1, tgt0.get_signature(), m_cols1, cols2, proj_cols);
|
|
t1->deallocate();
|
|
tgt.update(*t2);
|
|
t2->deallocate();
|
|
}
|
|
};
|
|
|
|
table_intersection_filter_fn * skip_table_plugin::mk_filter_by_negation_fn(
|
|
const table_base & t,
|
|
const table_base & negated_obj, unsigned joined_col_cnt,
|
|
const unsigned * t_cols, const unsigned * negated_cols) {
|
|
|
|
if (check_kind(t) && check_kind(negated_obj)) {
|
|
return alloc(filter_by_negation_fn, t, negated_obj, joined_col_cnt, t_cols, negated_cols);
|
|
}
|
|
TRACE("dl", tout << "could not handle operation\n";);
|
|
return 0;
|
|
}
|
|
|
|
bool skip_table_plugin::can_handle_signature(table_signature const& sig) {
|
|
for (unsigned i = 0; i < sig.size(); ++i) {
|
|
if (sig[i] >= UINT_MAX) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// ------------------
|
|
// skip_table
|
|
|
|
|
|
skip_table::skip_table(skip_table_plugin & p, const table_signature & sig):
|
|
table_base(p, sig),
|
|
m_imdd(p.get_imdd_manager().mk_empty(sig.size()), p.get_imdd_manager()) {
|
|
SASSERT(well_formed());
|
|
}
|
|
|
|
skip_table::skip_table(skip_table_plugin & p, const table_signature & sig, imdd* m):
|
|
table_base(p, sig),
|
|
m_imdd(m, p.get_imdd_manager()) {
|
|
SASSERT(well_formed());
|
|
}
|
|
|
|
skip_table::~skip_table() {
|
|
}
|
|
|
|
|
|
bool skip_table::well_formed() const {
|
|
table_signature const& sig = get_signature();
|
|
return
|
|
get_plugin().can_handle_signature(sig) &&
|
|
(get_imdd()->get_arity() == sig.size());
|
|
}
|
|
|
|
bool skip_table::empty() const {
|
|
return get_imdd()->empty();
|
|
}
|
|
|
|
void skip_table::update(imdd* n) {
|
|
m_imdd = n;
|
|
SASSERT(well_formed());
|
|
}
|
|
|
|
void skip_table::add_fact(const table_fact & f) {
|
|
imdd_manager& m = get_plugin().get_imdd_manager();
|
|
unsigned const* fact = get_fact(f.c_ptr());
|
|
m.add_fact(get_imdd(), m_imdd, f.size(), fact);
|
|
SASSERT(well_formed());
|
|
}
|
|
|
|
void skip_table::remove_fact(const table_element* f) {
|
|
imdd_manager& m = get_imdd_manager();
|
|
unsigned const* fact = get_fact(f);
|
|
m.remove_facts(get_imdd(), m_imdd, get_signature().size(), fact, fact);
|
|
}
|
|
|
|
bool skip_table::contains_fact(const table_fact & f) const {
|
|
imdd_manager& m = get_imdd_manager();
|
|
unsigned const* fact = get_fact(f.c_ptr());
|
|
return m.contains(get_imdd(), f.size(), fact);
|
|
}
|
|
|
|
table_base * skip_table::clone() const {
|
|
return alloc(skip_table, get_plugin(), get_signature(), get_imdd());
|
|
}
|
|
|
|
table_base * skip_table::complement() const {
|
|
imdd_manager& m = get_plugin().get_imdd_manager();
|
|
table_signature const& sig = get_signature();
|
|
unsigned_vector mins, maxs;
|
|
for (unsigned i = 0; i < sig.size(); ++i) {
|
|
SASSERT(sig[i] < UINT_MAX);
|
|
mins.push_back(0);
|
|
maxs.push_back(static_cast<unsigned>(sig[i]));
|
|
}
|
|
imdd_ref cmpl(m);
|
|
m.mk_complement(get_imdd(), cmpl, sig.size(), mins.c_ptr(), maxs.c_ptr());
|
|
return alloc(skip_table, get_plugin(), get_signature(), cmpl);
|
|
}
|
|
|
|
unsigned const* skip_table::get_fact(table_element const* f) const {
|
|
table_signature const& sig = get_signature();
|
|
const_cast<unsigned_vector&>(m_fact).reset();
|
|
for (unsigned i = 0; i < sig.size(); ++i) {
|
|
const_cast<unsigned_vector&>(m_fact).push_back(static_cast<unsigned>(f[i]));
|
|
SASSERT(f[i] < UINT_MAX);
|
|
}
|
|
return m_fact.c_ptr();
|
|
}
|
|
|
|
|
|
|
|
class skip_table::our_iterator_core : public table_base::iterator_core {
|
|
skip_table const& m_table;
|
|
imdd_manager::iterator m_iterator;
|
|
|
|
class our_row : public row_interface {
|
|
const our_iterator_core & m_parent;
|
|
public:
|
|
our_row(const our_iterator_core & parent) : row_interface(parent.m_table), m_parent(parent) {}
|
|
|
|
virtual void get_fact(table_fact & result) const {
|
|
result.reset();
|
|
unsigned arity = m_parent.m_iterator.get_arity();
|
|
unsigned const* values = *(m_parent.m_iterator);
|
|
for (unsigned i = 0; i < arity; ++i) {
|
|
result.push_back(values[i]);
|
|
}
|
|
}
|
|
virtual table_element operator[](unsigned col) const {
|
|
SASSERT(col < m_parent.m_iterator.get_arity());
|
|
unsigned const* values = *(m_parent.m_iterator);
|
|
return values[col];
|
|
}
|
|
};
|
|
|
|
our_row m_row_obj;
|
|
|
|
public:
|
|
struct b {};
|
|
struct e {};
|
|
|
|
our_iterator_core(skip_table const& t, b):
|
|
m_table(t),
|
|
m_iterator(t.m_imdd.get_manager(), t.get_imdd()),
|
|
m_row_obj(*this) {}
|
|
|
|
our_iterator_core(skip_table const& t, e):
|
|
m_table(t),
|
|
m_iterator(),
|
|
m_row_obj(*this) {}
|
|
|
|
virtual bool is_finished() const {
|
|
return m_iterator == imdd_manager::iterator();
|
|
}
|
|
|
|
virtual row_interface & operator*() {
|
|
SASSERT(!is_finished());
|
|
return m_row_obj;
|
|
}
|
|
|
|
virtual void operator++() {
|
|
SASSERT(!is_finished());
|
|
++m_iterator;
|
|
}
|
|
};
|
|
|
|
|
|
table_base::iterator skip_table::begin() const {
|
|
return mk_iterator(alloc(our_iterator_core, *this, our_iterator_core::b()));
|
|
}
|
|
|
|
table_base::iterator skip_table::end() const {
|
|
return mk_iterator(alloc(our_iterator_core, *this, our_iterator_core::e()));
|
|
}
|
|
|
|
unsigned skip_table::get_size_estimate_rows() const {
|
|
imdd_manager& m = get_plugin().get_imdd_manager();
|
|
size_t sz = m.get_num_rows(get_imdd());
|
|
unsigned sz0 = static_cast<unsigned>(sz);
|
|
SASSERT (sz == sz0 && "we need to use size_t or big-ints for row count");
|
|
return sz0;
|
|
}
|
|
|
|
unsigned skip_table::get_size_estimate_bytes() const {
|
|
imdd_manager& m = get_plugin().get_imdd_manager();
|
|
return m.memory(get_imdd());
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|