/// Breaks up the aggregation and uploads each piece separately. /// Audit groups do not nest. Therefore, when we see an aggregating /// cmd while already within an audit group, the "outer" group becomes /// invalid. This method traverses an audit group, publishes each of /// its audits individually, and destroys the group, thus clearing /// the way for the "inner" group to take over. /// @param[in] ldr the leader object pointer /// @param[in] process a function pointer to the publishing callback void ca_disband(ca_o ldr, void (*process) (ca_o)) { hnode_t *hnp; ck_o ck; ca_o sub; hscan_t hscan; _ca_verbosity_ag(ldr, "DISBANDING", NULL); hash_scan_begin(&hscan, ldr->ca_group_hash); for (hnp = hash_scan_next(&hscan); hnp; hnp = hash_scan_next(&hscan)) { ck = (ck_o)hnode_getkey(hnp); sub = (ca_o)hnode_get(hnp); if (ca_get_closed(sub)) { _ca_verbosity_ag(sub, "PROCESSING", NULL); ca_coalesce(sub); process(sub); } else { _ca_verbosity_ag(sub, "RELEASING", NULL); } ca_set_leader(sub, NULL); hash_scan_delete(ldr->ca_group_hash, hnp); hnode_destroy(hnp); ck_destroy(ck); } if (ca_get_closed(ldr)) { _ca_verbosity_ag(ldr, "PROCESSING", NULL); ca_coalesce(ldr); process(ldr); } else { _ca_verbosity_ag(ldr, "RELEASING", NULL); } hash_destroy(ldr->ca_group_hash); ldr->ca_group_hash = NULL; ca_set_leader(ldr, NULL); }
/// Finish off the CA by formatting it and sending it off. /// @param[in] ca the object pointer /// @param[in] process a function pointer to the publishing callback void ca_publish(ca_o ca, void (*process) (ca_o)) { _ca_verbosity_ag(ca, "BUNDLING", NULL); // Combine the textual command lines of the subcommands for record keeping. if (ca->ca_group_hash) { hscan_t hscan; hnode_t *hnp; ck_o ck; ca_o sub; hash_scan_begin(&hscan, ca->ca_group_hash); for (hnp = hash_scan_next(&hscan); hnp; hnp = hash_scan_next(&hscan)) { ck = (ck_o)hnode_getkey(hnp); sub = (ca_o)hnode_get(hnp); if (sub != ca) { _ca_verbosity_ag(sub, "MERGING", NULL); ca_merge(ca, sub); ca_set_processed(sub, 1); } hash_scan_delete(ca->ca_group_hash, hnp); hnode_destroy(hnp); ck_destroy(ck); } hash_destroy(ca->ca_group_hash); ca->ca_group_hash = NULL; } // Merge all PAs in subcommands in with the PA set of the leader. // Must be done before serializing for upload but after subcmds // are merged in. ca_coalesce(ca); // The sub CAs have now been sucked dry. Publish the fully merged leader. process(ca); }
void cmd_hnode_free(hnode_t *h, void *ignored) { bdestroy(hnode_get(h)); hnode_destroy(h); }