Skip to content

Commit 9ef2878

Browse files
committed
state match
1 parent 103cf5b commit 9ef2878

File tree

2 files changed

+93
-3
lines changed

2 files changed

+93
-3
lines changed

src/modules/job-list/match.c

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "match.h"
2424

2525
typedef bool (*match_f) (struct list_constraint *, const struct job *);
26+
typedef struct list_constraint * (*create_f) (json_t *, flux_error_t *);
2627
typedef int (*array_to_bitmask_f) (json_t *, flux_error_t *);
2728

2829
struct list_constraint {
@@ -84,6 +85,8 @@ static bool match_not (struct list_constraint *c, const struct job *job)
8485
}
8586

8687
static struct list_constraint *conditional_constraint (const char *type,
88+
match_f match_not_cb,
89+
create_f create_cb,
8790
json_t *values,
8891
flux_error_t *errp)
8992
{
@@ -103,11 +106,11 @@ static struct list_constraint *conditional_constraint (const char *type,
103106
else if (streq (type, "or"))
104107
c->match = match_or;
105108
else if (streq (type, "not"))
106-
c->match = match_not;
109+
c->match = match_not_cb;
107110
zlistx_set_destructor (c->values, list_constraint_destructor);
108111

109112
json_array_foreach (values, index, entry) {
110-
struct list_constraint *cp = list_constraint_create (entry, errp);
113+
struct list_constraint *cp = create_cb (entry, errp);
111114
if (!cp)
112115
goto error;
113116
if (!zlistx_add_end (c->values, cp)) {
@@ -450,7 +453,11 @@ struct list_constraint *list_constraint_create (json_t *constraint,
450453
else if (streq (op, "since"))
451454
return create_since_constraint (values, errp);
452455
else if (streq (op, "or") || streq (op, "and") || streq (op, "not"))
453-
return conditional_constraint (op, values, errp);
456+
return conditional_constraint (op,
457+
match_not,
458+
list_constraint_create,
459+
values,
460+
errp);
454461
else {
455462
errprintf (errp, "unknown constraint operator: %s", op);
456463
return NULL;
@@ -466,5 +473,75 @@ bool job_match (const struct job *job, struct list_constraint *constraint)
466473
return constraint->match (constraint, job);
467474
}
468475

476+
static bool match_not_checkempty (struct list_constraint *c, const struct job *job)
477+
{
478+
struct list_constraint *cp = zlistx_first (c->values);
479+
bool ran_a_match = false;
480+
while (cp) {
481+
if (!cp->match (cp, job))
482+
return true;
483+
if (cp->match != match_empty)
484+
ran_a_match = true;
485+
cp = zlistx_next (c->values);
486+
}
487+
/* if no real match callbacks were run, assume this conditional is true */
488+
if (!ran_a_match)
489+
return true;
490+
return false;
491+
}
492+
493+
struct list_constraint *state_constraint_create (json_t *constraint,
494+
flux_error_t *errp)
495+
{
496+
const char *op;
497+
json_t *values;
498+
499+
if (!constraint || !json_is_object (constraint)) {
500+
errprintf (errp, "constraint must be JSON object");
501+
return NULL;
502+
}
503+
if (json_object_size (constraint) > 1) {
504+
errprintf (errp, "constraint must only contain 1 element");
505+
return NULL;
506+
}
507+
json_object_foreach (constraint, op, values) {
508+
if (!json_is_array (values)) {
509+
errprintf (errp, "operator %s values not an array", op);
510+
return NULL;
511+
}
512+
if (streq (op, "userid")
513+
|| streq (op, "name")
514+
|| streq (op, "queue")
515+
|| streq (op, "results")
516+
|| streq (op, "since"))
517+
return list_constraint_new (errp);
518+
else if (streq (op, "states"))
519+
return create_states_constraint (values, errp);
520+
else if (streq (op, "or") || streq (op, "and") || streq (op, "not"))
521+
return conditional_constraint (op,
522+
match_not_checkempty,
523+
state_constraint_create,
524+
values,
525+
errp);
526+
else {
527+
errprintf (errp, "unknown constraint operator: %s", op);
528+
return NULL;
529+
}
530+
}
531+
return list_constraint_new (errp);
532+
}
533+
534+
bool state_match (flux_job_state_t state, struct list_constraint *constraint)
535+
{
536+
int valid_states = (FLUX_JOB_STATE_ACTIVE | FLUX_JOB_STATE_INACTIVE);
537+
struct job job;
538+
539+
if (!state || (state & ~valid_states) || !constraint)
540+
return false;
541+
542+
job.state = state;
543+
return constraint->match (constraint, &job);
544+
}
545+
469546
/* vi: ts=4 sw=4 expandtab
470547
*/

src/modules/job-list/match.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,17 @@ void list_constraint_destroy (struct list_constraint *constraint);
3535
*/
3636
bool job_match (const struct job *job, struct list_constraint *constraint);
3737

38+
/* Identical to list_constraint_create() but only cares about
39+
* "states" operation. Effectively tests the 'states' constraint
40+
* operation and conditionals with 'states', everything else is
41+
* considered true all of the time.
42+
*/
43+
struct list_constraint *state_constraint_create (json_t *constraint,
44+
flux_error_t *errp);
45+
46+
/* determines if a job in 'state' could potentially return true with
47+
* the given constraint.
48+
*/
49+
bool state_match (flux_job_state_t state, struct list_constraint *constraint);
50+
3851
#endif /* !HAVE_JOB_LIST_MATCH_H */

0 commit comments

Comments
 (0)