void test_code(char *code, node *result) { (void) yy_scan_string(code); parse(); if (node_cmp(NODE_RESULT, result) == 0) SUCCESSES++; else { FAILURES++; printf("FAIL %s => %s\n", code, node_string(NODE_RESULT, 1)); } }
static void do_print_nodes_diff(const struct epoch_log *log1, const struct epoch_log *log2, uint16_t flags, char act) { int i, j, nr_disk1 = 0, nr_disk2 = 0; const struct sd_node *entry1, *entry2; bool first = true; for (i = 0; i < log1->nr_nodes; i++) { entry1 = log1->nodes + i; if (flags & SD_CLUSTER_FLAG_DISKMODE) { for (nr_disk1 = 0; nr_disk1 < DISK_MAX; nr_disk1++) { if (entry1->disks[nr_disk1].disk_id == 0) break; } } for (j = 0; j < log2->nr_nodes; j++) { entry2 = log2->nodes + j; if (flags & SD_CLUSTER_FLAG_DISKMODE) { for (nr_disk2 = 0; nr_disk2 < DISK_MAX; nr_disk2++) { if (entry2->disks[nr_disk2].disk_id == 0) break; } } if (node_cmp(entry1, entry2) == 0 && nr_disk1 == nr_disk2) break; } if (j == log2->nr_nodes) { if (flags & SD_CLUSTER_FLAG_DISKMODE) printf("%s%c%s(%d)", first ? "" : ", ", act, addr_to_str(entry1->nid.addr, entry1->nid.port), nr_disk1); else printf("%s%c%s", first ? "" : ", ", act, addr_to_str(entry1->nid.addr, entry1->nid.port)); first = false; } } }
static int lnode_cmp(const struct local_node *a, const struct local_node *b) { return node_cmp(&a->node, &b->node); }
void reduce() { computeCost(root_); reducible_[0].push_back(root_); // sort reducible by reduce_cost for (unsigned i=0;i<InsertPolicy::MAX_LEVELS;++i) { std::sort(reducible_[i].begin(), reducible_[i].end(),node_cmp()); } while (colors_ > max_colors_ && colors_ > 1) { while (leaf_level_ >0 && reducible_[leaf_level_-1].size() == 0) { --leaf_level_; } if (leaf_level_ <= 0) { return; } // select best of all reducible: unsigned red_idx = leaf_level_-1; unsigned bestv = static_cast<unsigned>((*reducible_[red_idx].begin())->reduce_cost); for(unsigned i=red_idx; i>=InsertPolicy::MIN_LEVELS; i--) { if (!reducible_[i].empty()) { node *nd = *reducible_[i].begin(); unsigned gch = 0; for(unsigned idx=0; idx<8; idx++) { if (nd->children_[idx]) gch += nd->children_[idx]->children_count; } if (gch==0 && nd->reduce_cost < bestv) { bestv = static_cast<unsigned>(nd->reduce_cost); red_idx = i; } } } typename std::deque<node*>::iterator pos = reducible_[red_idx].begin(); node * cur_node = *pos; unsigned num_children = 0; for (unsigned idx=0; idx < 8; ++idx) { if (cur_node->children_[idx] != 0) { cur_node->children_count--; ++num_children; cur_node->count += cur_node->children_[idx]->count; //todo: case of nonleaf children, if someday sorting by reduce_cost doesn't handle it delete cur_node->children_[idx], cur_node->children_[idx]=0; } } reducible_[red_idx].erase(pos); if (num_children > 0 ) { colors_ -= (num_children - 1); } } }
static int node_insert( const void *val1, const void *val2 ) { /* Never return equal so that new entries are always inserted */ return node_cmp( val1, val2 ) < 0 ? -1 : 1; }
static int local_dispatch(void) { int ret; struct signalfd_siginfo siginfo; struct local_event *ev; enum cluster_join_result res; static struct work work = { .fn = local_block, .done = local_block_done, }; dprintf("read siginfo\n"); ret = read(sigfd, &siginfo, sizeof(siginfo)); assert(ret == sizeof(siginfo)); shm_queue_lock(); ev = shm_queue_peek(); if (!ev) goto out; switch (ev->type) { case EVENT_JOIN: if (ev->blocked) { if (node_cmp(&ev->nodes[0], &this_node) == 0) { res = local_check_join_cb(&ev->sender, ev->buf); ev->join_result = res; ev->blocked = 0; msync(ev, sizeof(*ev), MS_SYNC); shm_queue_notify(); if (res == CJ_RES_MASTER_TRANSFER) { eprintf("failed to join sheepdog cluster: please retry when master is up\n"); shm_queue_unlock(); exit(1); } } goto out; } if (ev->join_result == CJ_RES_MASTER_TRANSFER) { /* FIXME: This code is tricky, but Sheepdog assumes that */ /* nr_nodes = 1 when join_result = MASTER_TRANSFER... */ ev->nr_nodes = 1; ev->nodes[0] = this_node; ev->pids[0] = getpid(); shm_queue_set_chksum(); } lhdlrs.join_handler(&ev->sender, ev->nodes, ev->nr_nodes, ev->join_result, ev->buf); break; case EVENT_LEAVE: lhdlrs.leave_handler(&ev->sender, ev->nodes, ev->nr_nodes); break; case EVENT_NOTIFY: if (ev->blocked) { if (node_cmp(&ev->sender, &this_node) == 0) { if (!ev->callbacked) { queue_work(local_block_wq, &work); ev->callbacked = 1; } } goto out; } lhdlrs.notify_handler(&ev->sender, ev->buf, ev->buf_len); break; } shm_queue_pop(); out: shm_queue_unlock(); return 0; }