gchar * gegl_instrument_utf8 (void) { GString *s = g_string_new (""); gchar *ret; Timing *iter = root; sort_children (root); while (iter) { gchar *buf; if (!strcmp (iter->name, root->name)) { buf = g_strdup_printf ("Total time: %.3fs\n", seconds (iter->usecs)); s = g_string_append (s, buf); g_free (buf); } s = tab_to (s, timing_depth (iter) * INDENT_SPACES); s = g_string_append (s, iter->name); s = tab_to (s, SECONDS_COL); buf = g_strdup_printf ("%5.1f%%", iter->parent ? 100.0 * iter->usecs / iter->parent->usecs : 100.0); s = g_string_append (s, buf); g_free (buf); s = tab_to (s, BAR_COL); s = bar (s, BAR_WIDTH, normalized (iter->usecs)); s = g_string_append (s, "\n"); if (timing_depth (iter_next (iter)) < timing_depth (iter)) { if (timing_other (iter->parent) > 0) { s = tab_to (s, timing_depth (iter) * INDENT_SPACES); s = g_string_append (s, "other"); s = tab_to (s, SECONDS_COL); buf = g_strdup_printf ("%5.1f%%", 100 * normalized (timing_other (iter->parent))); s = g_string_append (s, buf); g_free (buf); s = tab_to (s, BAR_COL); s = bar (s, BAR_WIDTH, normalized (timing_other (iter->parent))); s = g_string_append (s, "\n"); } s = g_string_append (s, "\n"); } iter = iter_next (iter); } ret = g_strdup (s->str); g_string_free (s, TRUE); return ret; }
static void sort_children (Timing *parent) { Timing *iter; Timing *prev; gboolean changed = FALSE; do { iter = parent->children; changed = FALSE; prev = NULL; while (iter && iter->next) { Timing *next = iter->next; if (next->usecs > iter->usecs) { changed = TRUE; if (prev) { prev->next = next; iter->next = next->next; next->next = iter; } else { iter->next = next->next; next->next = iter; parent->children = next; } } prev = iter; iter = iter->next; } } while (changed); iter = parent->children; while (iter && iter->next) { sort_children (iter); iter = iter->next; } }
void Patricia::Node::add_child(allocator<Node*> &a, IMatcher &m, const u8 *b, int l, void *p) { if (l == 0) { //l == 0でここに来るということは,このノード自身とマッチしているということなので、param_を設定する. param_ = p; return; } for (auto iter = children_.begin(); iter != children_.end(); iter++) { Node *child = *iter; int ofs = 0, i = m.match(b, l, child->bytes_, child->len_, &ofs); if (i > 0) { //child->bytes_のi byteまでで部分一致し、その時bはofs byte読まれた. //一般的なmatchについてi != ofsだが、短いものにマッチしているということは、短い方がより汎用的な表現であると仮定する. //したがって、短い方をこのノードのchildとして残すノードのデータとして採用する.child->bytes_, bをスプリットして, //child->bytes_[0:i] or b[0:ofs]のうち短い方をこのノードのchildとして残し、child->bytes_[i + 1:]とb[ofs + 1:]をその子供に追加する. //child->bytes_[i + 1:]を保持するノードは今のノードの子供を引き継ぐ. Node *r, *b1, *b2, *new_parent; bool term; //rが終端ノードになるケース = child->len_ == i or ofs == l //child->len_ == iとなるケース: b, lがchild->bytes_, len_を含んでいる場合. r = (bytes_, len_)となるため終端となる //ofs == lとなるケース: b, lがchild->bytes_, len_に含まれている場合, r = (b, l)となるため終端となる. //終端となった場合、長さ0のデータを含むノードは作成しない if (i < ofs) { term = (child->len_ == i); r = Node::new_node(a, this, child->bytes_, i, term ? child->param_ : nullptr); b1 = Node::new_node(a, r, b + ofs, l - ofs, p); if (term) { //b2が作成されないため、rを子供を引き継ぐノードにする. new_parent = r; } else { b2 = Node::new_node(a, r, child->bytes_ + i, child->len_ - i, child->param_); new_parent = b2; } } else { term = (l == ofs); r = Node::new_node(a, this, b, ofs, term ? p : nullptr); b1 = Node::new_node(a, r, child->bytes_ + i, child->len_ - i, child->param_); //b1は必ず作成される(l == ofs かつ len_ == iなら一致してしまうため、このようなことは発生しない) new_parent = b1; if (!term) { b2 = Node::new_node(a, r, b + ofs, l - ofs, p); } } //このchildを取り除く.全てのリンクはまだ生きている. children_.erase(iter); //b1に今のchildのchild_を全部くっつける. for (Node *n : child->children_) { n->parent_ = new_parent; //parentをnew_parentにとっかえる. } new_parent->children_ = std::move(child->children_); //moveしてくれるのでcopy発生しないはず. //tにb1, b2を追加する.(new_parentはb1かb2のどちらかであるため、追加しなくて良い) r->children_.push_back(b1); if (!term) { r->children_.push_back(b2); r->sort_children();//辞書順に並べる. } //tを新しく追加する. children_.push_back(r); sort_children();//辞書順に並べる. //childは解放する. child->free(a); return; } } //全く一致するchildがなかったので新しく追加する.このノードは終端となる. children_.push_back(Node::new_node(a, this, b, l, p)); }
/** * the main code that does the zookeeper leader * election. this code creates its own ephemeral * node on the given path and sees if its the first * one on the list and claims to be a leader if and only * if its the first one of children in the paretn path */ static int zkr_lock_operation(zkr_lock_mutex_t *mutex, struct timespec *ts) { zhandle_t *zh = mutex->zh; char *path = mutex->path; char *id = mutex->id; struct Stat stat; char* owner_id = NULL; int retry = 3; do { const clientid_t *cid = zoo_client_id(zh); // get the session id int64_t session = cid->client_id; char prefix[30]; int ret = 0; #if defined(__x86_64__) snprintf(prefix, 30, "x-%016lx-", session); #else snprintf(prefix, 30, "x-%016llx-", session); #endif struct String_vector vectorst; vectorst.data = NULL; vectorst.count = 0; ret = ZCONNECTIONLOSS; ret = retry_getchildren(zh, path, &vectorst, ts, retry); if (ret != ZOK) return ret; struct String_vector *vector = &vectorst; mutex->id = lookupnode(vector, prefix); free_String_vector(vector); if (mutex->id == NULL) { int len = strlen(path) + strlen(prefix) + 2; char buf[len]; char retbuf[len+20]; snprintf(buf, len, "%s/%s", path, prefix); ret = ZCONNECTIONLOSS; ret = zoo_create(zh, buf, NULL, 0, mutex->acl, ZOO_EPHEMERAL|ZOO_SEQUENCE, retbuf, (len+20)); // do not want to retry the create since // we would end up creating more than one child if (ret != ZOK) { LOG_WARN(("could not create zoo node %s", buf)); return ret; } mutex->id = getName(retbuf); } if (mutex->id != NULL) { ret = ZCONNECTIONLOSS; ret = retry_getchildren(zh, path, vector, ts, retry); if (ret != ZOK) { LOG_WARN(("could not connect to server")); return ret; } //sort this list sort_children(vector); owner_id = vector->data[0]; mutex->ownerid = strdup(owner_id); id = mutex->id; char* lessthanme = child_floor(vector->data, vector->count, id); if (lessthanme != NULL) { int flen = strlen(mutex->path) + strlen(lessthanme) + 2; char last_child[flen]; sprintf(last_child, "%s/%s",mutex->path, lessthanme); ret = ZCONNECTIONLOSS; LOG_WARN(("retry-exists-1")); ret = retry_zoowexists(zh, last_child, &lock_watcher_fn, mutex, &stat, ts, retry); LOG_WARN(("retry-exists-2")); // cannot watch my predecessor i am giving up // we need to be able to watch the predecessor // since if we do not become a leader the others // will keep waiting if (ret != ZOK) { free_String_vector(vector); LOG_WARN(("unable to watch my predecessor")); ret = zkr_lock_unlock(mutex); while (ret == 0) { //we have to give up our leadership // since we cannot watch out predecessor ret = zkr_lock_unlock(mutex); } return ret; } // we are not the owner of the lock mutex->isOwner = 0; } else { // this is the case when we are the owner // of the lock if (strcmp(mutex->id, owner_id) == 0) { LOG_DEBUG(("got the zoo lock owner - %s", mutex->id)); mutex->isOwner = 1; if (mutex->completion != NULL) { mutex->completion(0, mutex->cbdata); } return ZOK; } } free_String_vector(vector); return ZOK; } } while (mutex->id == NULL); return ZOK; }