void TEST_Construction() { Hashtable h; h.resize(26); Item a = {"a", 'a'}; Item b = {"b", 'b'}; Item c = {"c", 'c'}; Item abcd1234 = {"abcd1234", 99}; Item abcdefghijklmnopqrstuv = {"abcdefghijklmnopqrstuv", 101}; insert(&h, &a); ASSERT_EQ(h[simple_hash::hash("a") % h.size()]->value,'a'); insert(&h, &b); ASSERT_EQ(h[simple_hash::hash("b") % h.size()]->value,'b'); insert(&h, &c); ASSERT_EQ(h[simple_hash::hash("c") % h.size()]->value,'c'); insert(&h, &abcd1234); ASSERT_EQ(h[simple_hash::hash("abcd1234") % h.size()]->value, 'a'); ASSERT_EQ(h[simple_hash::hash("abcd1234") % h.size() + 1]->value, 'b'); ASSERT_EQ(h[simple_hash::hash("abcd1234") % h.size() + 2]->value, 'c'); ASSERT_EQ(h[simple_hash::hash("abcd1234") % h.size() + 3]->value, 99); insert(&h, &abcdefghijklmnopqrstuv); ASSERT_EQ(h[simple_hash::hash("abcd1234") % h.size()]->value, 'a'); ASSERT_EQ(h[simple_hash::hash("abcd1234") % h.size() + 1]->value, 'b'); ASSERT_EQ(h[simple_hash::hash("abcd1234") % h.size() + 2]->value, 'c'); ASSERT_EQ(h[simple_hash::hash("abcd1234") % h.size() + 3]->value, 99); ASSERT_EQ(h[simple_hash::hash("abcdefghijklmnopqrstuv") % h.size() + 4]->value, 101); }
Handle_ptr hashsizeCommand( CBuiltinAdapter *adapter, Context &ctx, Environment *env, std::vector<Handle_ptr> args) { if (1 != args.size()) { throw ArgumentCountException( 1, __FILE__, __LINE__); } Hashtable *hashtable = asHashtable( args[0]); assert( 0 != hashtable); return ctx.factory->makeInteger( hashtable->size()); }
void TEST_Resizing() { Hashtable h; h.resize(26); Item a = {"a", 'a'}; Item b = {"b", 'b'}; Item c = {"c", 'c'}; Item abcd1234 = {"abcd1234", 99}; Item abcdefghijklmnopqrstuv = {"abcdefghijklmnopqrstuv", 101}; ASSERT_EQ(find(&h, "blah"), nullptr); insert(&h, &a); ASSERT_EQ(find(&h, a.key), &a); insert(&h, &b); ASSERT_EQ(find(&h, b.key), &b); insert(&h, &c); ASSERT_EQ(find(&h, c.key), &c); insert(&h, &abcd1234); ASSERT_EQ(find(&h, abcd1234.key), &abcd1234); insert(&h, &abcdefghijklmnopqrstuv); ASSERT_EQ(find(&h, abcdefghijklmnopqrstuv.key), &abcdefghijklmnopqrstuv); resize(&h, 52); ASSERT_EQ(h.size(), 52); ASSERT_EQ(find(&h, "blah"), nullptr); ASSERT_EQ(find(&h, a.key), &a); ASSERT_EQ(find(&h, b.key), &b); ASSERT_EQ(find(&h, c.key), &c); ASSERT_EQ(find(&h, abcd1234.key), &abcd1234); ASSERT_EQ(find(&h, abcdefghijklmnopqrstuv.key), &abcdefghijklmnopqrstuv); resize(&h, 13); ASSERT_EQ(h.size(), 13); ASSERT_EQ(find(&h, "blah"), nullptr); ASSERT_EQ(find(&h, a.key), &a); ASSERT_EQ(find(&h, b.key), &b); ASSERT_EQ(find(&h, c.key), &c); ASSERT_EQ(find(&h, abcd1234.key), &abcd1234); ASSERT_EQ(find(&h, abcdefghijklmnopqrstuv.key), &abcdefghijklmnopqrstuv); }
bool rhom_method_name_isreserved(const String& strName) { static Hashtable<String,int> reserved_names; if ( reserved_names.size() == 0 ) { reserved_names.put("object",1); reserved_names.put("source_id",1); reserved_names.put("update_type",1); reserved_names.put("attrib_type",1); reserved_names.put("set_notification",1); reserved_names.put("clear_notification",1); } return reserved_names.get(strName) != 0; }
GEODE_COLD static void assert_delaunay(const char* prefix, const TriangleTopology& mesh, RawField<const Perturbed2,VertexId> X, const Hashtable<Vector<VertexId,2>>& constrained=Tuple<>(), const bool oriented_only=false, const bool check_boundary=true) { // Verify that all faces are correctly oriented for (const auto f : mesh.faces()) { const auto v = mesh.vertices(f); GEODE_ASSERT(triangle_oriented(X,v.x,v.y,v.z)); } if (oriented_only) return; // Verify that all internal edges are Delaunay if (!constrained.size()) { for (const auto e : mesh.interior_halfedges()) if (!mesh.is_boundary(mesh.reverse(e)) && mesh.src(e)<mesh.dst(e)) if (!is_delaunay(mesh,X,e)) throw RuntimeError(format("%snon delaunay edge: e%d, v%d v%d",prefix,e.id,mesh.src(e).id,mesh.dst(e).id)); } else { for (const auto v : constrained) if (!mesh.halfedge(v.x,v.y).valid()) throw RuntimeError(format("%smissing constraint edge: v%d v%d",prefix,v.x.id,v.y.id)); for (const auto e : mesh.interior_halfedges()) { const auto s = mesh.src(e), d = mesh.dst(e); if (!mesh.is_boundary(mesh.reverse(e)) && s<d && !constrained.contains(vec(s,d))) if (!is_delaunay(mesh,X,e)) throw RuntimeError(format("%snon delaunay edge: e%d, v%d v%d",prefix,e.id,mesh.src(e).id,mesh.dst(e).id)); } } // Verify that all boundary vertices are convex if (check_boundary) for (const auto e : mesh.boundary_edges()) { const auto v0 = mesh.src(mesh.prev(e)), v1 = mesh.src(e), v2 = mesh.dst(e); GEODE_ASSERT(triangle_oriented(X,v2,v1,v0)); } }
// Do a clean evaluation of each board involved in an error or dependency static bool trace_learn() { // Copy errors and dependencies since they'll be cleared during clean evaluation auto errors = pentago::errors; auto dependencies = pentago::dependencies; // Learn about each error and each dependency int count = known.size(); for (auto error : errors) clean_evaluate(error.aggressive,error.depth,error.board); for (auto dep : dependencies) clean_evaluate(dep.aggressive,dep.depth,dep.board); // If we haven't learned anything new, evaluate the children of each error if (count<known.size()) return true; for (auto error : errors) { const bool aggressive = error.aggressive; const int depth = error.depth; GEODE_ASSERT(depth); const board_t board = error.board; const side_t side0 = unpack(board,0), side1 = unpack(board,1); // Evaluate all dependencies SIMPLE_MOVES(side0,side1); for (int i=0;i<total;i++) clean_evaluate(!aggressive,depth-1,pack(side1,moves[i])); // Verify that we're consistent with the child values super_t wins = 0; for (int r=0;r<256;r++) { const symmetry_t s(0,r); const bool verbose = (depth==5 && board==35466671711863625 && r==89) || (depth==4 && board==39688947336609933 && r==113); board_t rb = transform_board(s,board); board_t rside0 = transform_side(s,side0); if (verbose) cout << "\n\n\ntrace_learn: checking board "<<rb<<":\n"<<str_board(rb)<<endl; int st = status(rb); if (verbose) cout << "status = "<<st<<endl; if (st) wins |= (aggressive?st==1:st!=2) ? super_t::singleton(r) : super_t(0); else for (int i=0;i<total;i++) { const side_t rmove = transform_side(s,moves[i]); if (won(rmove)) { if (verbose) cout << "immediate win with move "<<str_move(rmove^rside0)<<endl; wins |= super_t::singleton(r); goto win; } else { board_t child = pack(side1,moves[i]); super_t child_wins = known_wins(depth-1,child); for (int q=0;q<4;q++) for (int d=1;d<=3;d+=2) { symmetry_t cs = symmetry_t(0,d<<2*q)*s; if (!child_wins(cs.local)) { if (verbose) { cout << "win with move "<<str_move(rmove^rside0)<<", rotation "<<q<<' '<<d<<endl; //cout << "rside0 =\n"<<str_board(pack(rside0,(side_t)0))<<endl; //cout << "rmove =\n"<<str_board(pack(rmove,(side_t)0))<<endl; } wins |= super_t::singleton(r); goto win; } } } } win: if (verbose) { if (!wins(r)) cout << "loss"<<endl; cout << "\n\n\n"; } } super_t parent_wins = known_wins(depth,board); super_t errors = wins^parent_wins; if (errors) { uint8_t r = first(errors); cout << format("trace_learn: inconsistent results for clean evaluation of depth %d, board %lld, aggressive %d: rotation %d, parent %d, children %d",depth,board,aggressive,r,parent_wins(r),wins(r))<<endl; return false; } } // If we still haven't learned anything new, any errors are immediate if (count<known.size()) return true; for (auto error : errors) cout << format("trace_learn: isolated error for depth %d, board %lld, aggressive %d",error.depth,error.board,error.aggressive)<<endl; return false; }