/*++ Copyright (c) 2006 Microsoft Corporation Module Name: total_order.cpp Abstract: Author: Leonardo de Moura (leonardo) 2010-07-01. Revision History: --*/ #include"total_order.h" #include"timeit.h" static void tst1() { uint_total_order to; to.insert(1); to.insert_after(1, 2); to.insert_after(1, 3); SASSERT(to.lt(1, 2)); SASSERT(to.lt(3, 2)); SASSERT(to.lt(1, 3)); SASSERT(!to.lt(2, 3)); SASSERT(!to.lt(3, 1)); SASSERT(!to.lt(2, 2)); std::cout << to << "\n"; } static void tst2() { uint_total_order to; to.insert(1); to.insert_after(1, 2); to.insert_after(2, 3); for (unsigned i = 0; i < 1000; i++) { to.move_after(3, 1); to.move_after(1, 2); to.move_after(2, 3); SASSERT(to.lt(1,2)); SASSERT(to.lt(2,3)); } } static void tst3(unsigned sz, unsigned num_rounds) { uint_total_order to; to.insert(0); for (unsigned i = 0; i < sz; i++) { to.insert_after(i, i+1); } for (unsigned i = 0; i < num_rounds; i++) { unsigned v1 = rand() % sz; unsigned v2 = rand() % sz; if (v1 != v2) to.move_after(v1, v2); if (i % 1000 == 0) { std::cout << "*"; std::cout.flush(); } } std::cout << std::endl; } void move_after(unsigned_vector & v, unsigned_vector & inv_v, unsigned a, unsigned b) { if (a == b) return; // std::cout << std::endl; // display(std::cout, v.begin(), v.end()); std::cout << std::endl; // std::cout << "move_after(" << a << ", " << b << ")\n"; unsigned pos_a = inv_v[a]; unsigned pos_b = inv_v[b]; SASSERT(pos_a != pos_b); if (pos_b < pos_a) { for (unsigned i = pos_b; i < pos_a; i++) { v[i] = v[i+1]; inv_v[v[i+1]] = i; } v[pos_a] = b; inv_v[b] = pos_a; SASSERT(inv_v[b] == inv_v[a] + 1); } else { SASSERT(pos_b > pos_a); for (unsigned i = pos_b; i > pos_a + 1; i--) { v[i] = v[i-1]; inv_v[v[i-1]] = i; } v[pos_a+1] = b; inv_v[b] = pos_a+1; SASSERT(inv_v[b] == inv_v[a] + 1); } // display(std::cout, v.begin(), v.end()); std::cout << std::endl; } static void tst4(unsigned sz, unsigned num_rounds) { uint_total_order to; unsigned_vector v; unsigned_vector inv_v; to.insert(0); v.push_back(0); inv_v.push_back(0); for (unsigned i = 0; i < sz; i++) { to.insert_after(i, i+1); v.push_back(i+1); inv_v.push_back(i+1); } for (unsigned i = 0; i < num_rounds; i++) { unsigned v1 = rand() % sz; unsigned v2 = rand() % sz; if (v1 != v2) { to.move_after(v1, v2); move_after(v, inv_v, v1, v2); } for (unsigned k = 0; k < sz - 1; k++) { SASSERT(inv_v[v[k]] == k); SASSERT(to.lt(v[k], v[k+1])); } if (i % 1000 == 0) { std::cout << "*"; std::cout.flush(); } } std::cout << std::endl; } static void bad_case(unsigned sz, unsigned num_rounds) { uint_total_order to; to.insert(0); for (unsigned i = 0; i < sz; i++) { to.insert_after(i, i+1); } for (unsigned i = 0; i < num_rounds; i++) { to.move_after(sz, 0); for (unsigned j = 0; j < sz; j++) { to.move_after(j, j+1); } if (i % 10 == 0) { std::cout << "*"; std::cout.flush(); } } std::cout << std::endl; } void tst_total_order() { bad_case(100, 1000); tst1(); tst2(); tst4(3, 1000000); tst4(100, 100000); tst4(512, 100000); tst4(1000, 100000); tst3(100, 100000); tst3(1000, 100000); }