static int attr_list_rpc (attr_ctx_t *ctx) { flux_future_t *f; json_t *array, *value; size_t index; int rc = -1; if (!(f = flux_rpc (ctx->h, "attr.list", NULL, FLUX_NODEID_ANY, 0))) goto done; if (flux_rpc_get_unpack (f, "{s:o}", "names", &array) < 0) goto done; zlist_destroy (&ctx->names); if (!(ctx->names = zlist_new ())) goto done; json_array_foreach (array, index, value) { const char *name = json_string_value (value); if (!name) { errno = EPROTO; goto done; } if (zlist_append (ctx->names, strdup (name)) < 0) { errno = ENOMEM; goto done; } } zlist_sort (ctx->names, (zlist_compare_fn *)attr_strcmp); rc = 0; done: flux_future_destroy (f); return rc; }
flux_kvsitr_t *flux_kvsitr_create (const flux_kvsdir_t *dir) { flux_kvsitr_t *itr = NULL; const char *key; json_t *dirdata, *value; if (!dir) { errno = EINVAL; goto error; } if (!(itr = calloc (1, sizeof (*itr)))) goto error; if (!(itr->keys = zlist_new ())) goto error; dirdata = treeobj_get_data (dir->dirobj); json_object_foreach (dirdata, key, value) { if (zlist_push (itr->keys, (char *)key) < 0) goto error; } zlist_sort (itr->keys, sort_cmp); itr->reset = true; return itr; error: flux_kvsitr_destroy (itr); return NULL; }
static int s_dir_flatten (zdir_t *self, zfile_t **files, int index) { // First flatten the normal files zlist_sort (self->files, s_file_compare); zfile_t *file = (zfile_t *) zlist_first (self->files); while (file) { files [index++] = file; file = (zfile_t *) zlist_next (self->files); } // Now flatten subdirectories, recursively zlist_sort (self->subdirs, s_dir_compare); zdir_t *subdir = (zdir_t *) zlist_first (self->subdirs); while (subdir) { index = s_dir_flatten (subdir, files, index); subdir = (zdir_t *) zlist_next (self->subdirs); } return index; }
static void emit_command_help_from_pattern (const char *pattern, FILE *fp) { zhash_t *zh = NULL; zlist_t *keys = NULL; const char *cat; zh = get_command_list_hash (pattern); if (zh == NULL) return; keys = zhash_keys (zh); zlist_sort (keys, (zlist_compare_fn *) category_cmp); cat = zlist_first (keys); while (cat) { emit_command_list_category (zh, cat, fp); if ((cat = zlist_next (keys))) fprintf (fp, "\n"); } zlist_destroy (&keys); zhash_destroy (&zh); return; }
void zlist_test (int verbose) { printf (" * zlist: "); // @selftest zlist_t *list = zlist_new (); assert (list); assert (zlist_size (list) == 0); // Three items we'll use as test data // List items are void *, not particularly strings char *cheese = "boursin"; char *bread = "baguette"; char *wine = "bordeaux"; zlist_append (list, cheese); assert (zlist_size (list) == 1); zlist_append (list, bread); assert (zlist_size (list) == 2); zlist_append (list, wine); assert (zlist_size (list) == 3); assert (zlist_head (list) == cheese); assert (zlist_next (list) == cheese); assert (zlist_first (list) == cheese); assert (zlist_tail (list) == wine); assert (zlist_next (list) == bread); assert (zlist_first (list) == cheese); assert (zlist_next (list) == bread); assert (zlist_next (list) == wine); assert (zlist_next (list) == NULL); // After we reach end of list, next wraps around assert (zlist_next (list) == cheese); assert (zlist_size (list) == 3); zlist_remove (list, wine); assert (zlist_size (list) == 2); assert (zlist_first (list) == cheese); zlist_remove (list, cheese); assert (zlist_size (list) == 1); assert (zlist_first (list) == bread); zlist_remove (list, bread); assert (zlist_size (list) == 0); zlist_append (list, cheese); zlist_append (list, bread); assert (zlist_last (list) == bread); zlist_remove (list, bread); assert (zlist_last (list) == cheese); zlist_remove (list, cheese); assert (zlist_last (list) == NULL); zlist_push (list, cheese); assert (zlist_size (list) == 1); assert (zlist_first (list) == cheese); zlist_push (list, bread); assert (zlist_size (list) == 2); assert (zlist_first (list) == bread); zlist_append (list, wine); assert (zlist_size (list) == 3); assert (zlist_first (list) == bread); zlist_sort (list, s_compare); char *item; item = (char *) zlist_pop (list); assert (item == bread); item = (char *) zlist_pop (list); assert (item == wine); item = (char *) zlist_pop (list); assert (item == cheese); assert (zlist_size (list) == 0); // Destructor should be safe to call twice zlist_destroy (&list); zlist_destroy (&list); assert (list == NULL); // @end printf ("OK\n"); }
JNIEXPORT void JNICALL Java_zlist__1_1sort (JNIEnv *env, jclass c, jlong self, jlong compare) { zlist_sort ((zlist_t *) self, (zlist_compare_fn *) compare); }
static void determine_all_min_bandwidth_helper (struct resource *r, double curr_min_bandwidth, zhash_t *job_hash) { struct resource *curr_child; int64_t job_id; double total_requested_bandwidth, curr_average_bandwidth, child_alloc_bandwidth, total_used_bandwidth, this_max_bandwidth, num_children, this_alloc_bandwidth; json_t *o; zlist_t *child_list; const char *type = NULL; // Check if leaf node in hierarchy (base case) rdl_resource_iterator_reset (r); curr_child = rdl_resource_next_child (r); if (curr_child == NULL) { // Check if allocated to a job if (rdl_resource_get_int (r, "lwj", &job_id) == 0) { // Determine which is less, the bandwidth currently available to // this resource, or the bandwidth allocated to it by the job // This assumes that jobs cannot share leaf nodes in the hierarchy this_alloc_bandwidth = get_alloc_bandwidth (r); curr_min_bandwidth = (curr_min_bandwidth < this_alloc_bandwidth) ? curr_min_bandwidth : this_alloc_bandwidth; double *job_min_bw = get_job_min_from_hash (job_hash, job_id); if (job_min_bw != NULL && curr_min_bandwidth < *job_min_bw) { *job_min_bw = curr_min_bandwidth; } // if job_min_bw is NULL, the tag still exists in the RDL, but // the job completed } return; } // else // Sum the bandwidths of the parent's children total_requested_bandwidth = 0; child_list = zlist_new (); while (curr_child != NULL) { o = rdl_resource_json (curr_child); Jget_str (o, "type", &type); // TODO: clean up this hardcoded value, should go away once we switch to // the real // rdl implementation (storing a bandwidth resource at every level) if (strcmp (type, "memory") != 0) { total_requested_bandwidth += get_alloc_bandwidth (curr_child); zlist_append (child_list, curr_child); } Jput (o); curr_child = rdl_resource_next_child (r); } rdl_resource_iterator_reset (r); // Sort child list based on alloc bw zlist_sort (child_list, compare_resource_alloc_bw); // const char *resource_string = Jtostr(o); // Loop over all of the children this_max_bandwidth = get_max_bandwidth (r); total_used_bandwidth = (total_requested_bandwidth > this_max_bandwidth) ? this_max_bandwidth : total_requested_bandwidth; total_used_bandwidth = (total_used_bandwidth > curr_min_bandwidth) ? curr_min_bandwidth : total_used_bandwidth; while (zlist_size (child_list) > 0) { // Determine the amount of bandwidth to allocate to each child num_children = zlist_size (child_list); curr_average_bandwidth = (total_used_bandwidth / num_children); curr_child = (struct resource *)zlist_pop (child_list); child_alloc_bandwidth = get_alloc_bandwidth (curr_child); if (child_alloc_bandwidth > 0) { if (child_alloc_bandwidth > curr_average_bandwidth) child_alloc_bandwidth = curr_average_bandwidth; // Subtract the allocated bandwidth from the parent's total total_used_bandwidth -= child_alloc_bandwidth; // Recurse on the child determine_all_min_bandwidth_helper (curr_child, child_alloc_bandwidth, job_hash); } rdl_resource_destroy (curr_child); } // Cleanup zlist_destroy ( &child_list); // no need to rdl_resource_destroy, done in above loop return; }
void zlist_test (bool verbose) { printf (" * zlist: "); // @selftest zlist_t *list = zlist_new (); assert (list); assert (zlist_size (list) == 0); // Three items we'll use as test data // List items are void *, not particularly strings char *cheese = "boursin"; char *bread = "baguette"; char *wine = "bordeaux"; zlist_append (list, cheese); assert (zlist_size (list) == 1); assert ( zlist_exists (list, cheese)); assert (!zlist_exists (list, bread)); assert (!zlist_exists (list, wine)); zlist_append (list, bread); assert (zlist_size (list) == 2); assert ( zlist_exists (list, cheese)); assert ( zlist_exists (list, bread)); assert (!zlist_exists (list, wine)); zlist_append (list, wine); assert (zlist_size (list) == 3); assert ( zlist_exists (list, cheese)); assert ( zlist_exists (list, bread)); assert ( zlist_exists (list, wine)); assert (zlist_head (list) == cheese); assert (zlist_next (list) == cheese); assert (zlist_first (list) == cheese); assert (zlist_tail (list) == wine); assert (zlist_next (list) == bread); assert (zlist_first (list) == cheese); assert (zlist_next (list) == bread); assert (zlist_next (list) == wine); assert (zlist_next (list) == NULL); // After we reach end of list, next wraps around assert (zlist_next (list) == cheese); assert (zlist_size (list) == 3); zlist_remove (list, wine); assert (zlist_size (list) == 2); assert (zlist_first (list) == cheese); zlist_remove (list, cheese); assert (zlist_size (list) == 1); assert (zlist_first (list) == bread); zlist_remove (list, bread); assert (zlist_size (list) == 0); zlist_append (list, cheese); zlist_append (list, bread); assert (zlist_last (list) == bread); zlist_remove (list, bread); assert (zlist_last (list) == cheese); zlist_remove (list, cheese); assert (zlist_last (list) == NULL); zlist_push (list, cheese); assert (zlist_size (list) == 1); assert (zlist_first (list) == cheese); zlist_push (list, bread); assert (zlist_size (list) == 2); assert (zlist_first (list) == bread); assert (zlist_item (list) == bread); zlist_append (list, wine); assert (zlist_size (list) == 3); assert (zlist_first (list) == bread); zlist_t *sub_list = zlist_dup (list); assert (sub_list); assert (zlist_size (sub_list) == 3); zlist_sort (list, s_compare); char *item; item = (char *) zlist_pop (list); assert (item == bread); item = (char *) zlist_pop (list); assert (item == wine); item = (char *) zlist_pop (list); assert (item == cheese); assert (zlist_size (list) == 0); assert (zlist_size (sub_list) == 3); zlist_push (list, sub_list); zlist_t *sub_list_2 = zlist_dup (sub_list); zlist_append (list, sub_list_2); assert (zlist_freefn (list, sub_list, &s_zlist_free, false) == sub_list); assert (zlist_freefn (list, sub_list_2, &s_zlist_free, true) == sub_list_2); zlist_destroy (&list); // Test autofree functionality list = zlist_new (); assert (list); zlist_autofree (list); // Set equals function otherwise equals will not work as autofree copies strings zlist_comparefn (list, s_compare); zlist_push (list, bread); zlist_append (list, cheese); assert (zlist_size (list) == 2); zlist_append (list, wine); assert (zlist_exists (list, wine)); zlist_remove (list, wine); assert (!zlist_exists (list, wine)); assert (streq ((const char *) zlist_first (list), bread)); item = (char *) zlist_pop (list); assert (streq (item, bread)); free (item); item = (char *) zlist_pop (list); assert (streq (item, cheese)); free (item); zlist_destroy (&list); assert (list == NULL); // @end printf ("OK\n"); }
/// // Sort the list by ascending key value using a straight ASCII comparison. // The sort is not stable, so may reorder items with the same keys. void QZlist::sort (zlist_compare_fn compare) { zlist_sort (self, compare); }
/* * reserve_resources() reserves resources for the specified job id. * Unlike the FCFS version where selected_tree provides the tree of * resources to reserve, this backfill version will search into the * future to find a time window when all of the required resources are * available, reserve those, and return the pointer to the selected * tree. */ int reserve_resources (flux_t h, resrc_tree_t **selected_tree, int64_t job_id, int64_t starttime, int64_t walltime, resrc_t *resrc, resrc_reqst_t *resrc_reqst) { int rc = -1; int64_t *completion_time = NULL; int64_t nfound = 0; int64_t prev_completion_time = -1; resrc_tree_t *found_tree = NULL; if (reservation_depth > 0 && (curr_reservation_depth >= reservation_depth)) { goto ret; } else if (!resrc || !resrc_reqst) { flux_log (h, LOG_ERR, "%s: invalid arguments", __FUNCTION__); goto ret; } if (*selected_tree) { resrc_tree_destroy (*selected_tree, false); *selected_tree = NULL; } zlist_sort (completion_times, compare_int64_ascending); for (completion_time = zlist_first (completion_times); completion_time; completion_time = zlist_next (completion_times)) { /* Purge past times from consideration */ if (*completion_time < starttime) { zlist_remove (completion_times, completion_time); continue; } /* Don't test the same time multiple times */ if (prev_completion_time == *completion_time) continue; resrc_reqst_set_starttime (resrc_reqst, *completion_time + 1); resrc_reqst_set_endtime (resrc_reqst, *completion_time + 1 + walltime); flux_log (h, LOG_DEBUG, "Attempting to reserve %"PRId64" nodes for job " "%"PRId64" at time %"PRId64"", resrc_reqst_reqrd_qty (resrc_reqst), job_id, *completion_time + 1); nfound = resrc_tree_search (resrc, resrc_reqst, &found_tree, true); if (nfound >= resrc_reqst_reqrd_qty (resrc_reqst)) { *selected_tree = select_resources (h, found_tree, resrc_reqst, NULL); resrc_tree_destroy (found_tree, false); if (*selected_tree) { rc = resrc_tree_reserve (*selected_tree, job_id, *completion_time + 1, *completion_time + 1 + walltime); if (rc) { resrc_tree_destroy (*selected_tree, false); *selected_tree = NULL; } else { curr_reservation_depth++; flux_log (h, LOG_DEBUG, "Reserved %"PRId64" nodes for job " "%"PRId64" from %"PRId64" to %"PRId64"", resrc_reqst_reqrd_qty (resrc_reqst), job_id, *completion_time + 1, *completion_time + 1 + walltime); } break; } } prev_completion_time = *completion_time; } ret: return rc; }