require

package module
Version: v0.0.0-...-074c49d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 25, 2020 License: Apache-2.0 Imports: 5 Imported by: 0

README

go-require

A general purpose, minimal requirements language.

Originally designed for scheduling systems, it's now generic enough to be reused across multiple domains, whererever simple predicate matching is needed.

go install -u ajz.dev/go/require

Syntax

~       # mark the expression as optional, but preferred
!       # negate the expression
label   # label (re: [^=<]*)
str     # arbitrary string (re: .*)
int     # integer (re: -?[0-9]+)
=       # equality op;
<       # less-than op; for labels: lexiographic by length.

[~] [!] label                    # label-matching expression
[~] [!] {label int} = {str num}  # exact value-matching expression
[~] [!] {label int} < {str num}  # lexiographic/numeric less-than
Examples
healthy       # require the label "healthy"
~healthy      # prefer the label "healthy"
color=blue    # require color "blue"
!color=green  # exclude color "green"
!ram<100      # ram is least 100 MiB
~u9n<50       # prefer utilization less than 50%.

Usage

Basic
s1 := Parse("~foo=2", "bar=baz", "baz<5")
s2 := Parse("a", "b", "c", "bar=baz", "baz=1")

var ctx require.Context
ctx.Add(s1...)

// Test:
if ctx.Test(s2...) {
    all required specs match!
}

// Score:
score := ctx.Score(s2...) // 0
Scoring

Find the best match among candidates.

var (
  best = -1
  bestScore = require.MinScore
  ctx require.Context
)
ctx.Add(s1...)
for i, s2 := range candidates {
  if score := ctx.Score(s2...); bestScore < score {
    best = i
    bestScore = score
    if threshold <= score {
      break
    }
  }
}

See more detail in package documentation.

Documentation

Overview

Package require implements a general purpose requirements language. The language was initially designed for scheduling systems, but can be used across similar domains where label and predicate matching is needed.

The language provides the base minimum required for representing basic requirements. Overview of symbols:

~       # mark the expression as optional, but preferred
!       # negate the expression
label   # label (re: [^=<]*)
str     # arbitrary string (re: .*)
int     # integer (re: -?[0-9]+)
=       # equality op;
<       # less-than op; for labels: lexiographic by length.

Overview of syntaxes:

[~] [!] label                    # label-matching expression
[~] [!] {label int} = {str num}  # exact value-matching expression
[~] [!] {label int} < {str num}  # lexiographic/numeric less-than

Examples of well-formed expressions:

healthy       # require the label "healthy"
~healthy      # prefer the label "healthy"
color=blue    # require color "blue"
!color=green  # exclude color "green"
!ram<100      # ram is least 100 MiB
~u9n<50       # prefer utilization less than 50%.

Testing compatibility of requirements:

Label and values expression tests work as one would expect. One note is the use of the optional marker: Given the condition "~foo", both "~foo" and "foo" match the expression. Specal handling is given to less-than conditions: Given the condition "bar<100", all conditions "bar<x" where x <= 100 match, and all conditions "bar=y" where y < 100 match.

Lexiographic order is used for strings: Given the condition "baz<fizz", all conditions "baz<x" where bytes.Compare(x, fizz) <= 0 match, and all conditions "baz=y" where bytes.Compare(y, fizz) < 0 match.

Test usage:

var ctx require.Context
ctx.Add(s1...)
if ctx.Test(s2...) {
	// all required specs match!
}

Scoring candidates:

This provides a integer score useful for comparing multiple options. Score takes a slice of ScoreOptions to provide a means to customize the scoring algorithms used.

Score usage (find the best match):

var (
	best = -1
	bestScore = require.MinScore
	ctx require.Context
)
ctx.Add(s1...)
for i, s2 := range candidates {
	if score := ctx.Score(s2...); bestScore < score {
		best = i
		bestScore = score
		if threshold <= score {
			break
		}
	}
}

Index

Constants

View Source
const (
	// MinScore is the minimum score returned from Score if Test fails.
	MinScore = int64(-math.MaxInt64)
)

Variables

This section is empty.

Functions

func Sort

func Sort(specs []Spec)

Sort parsed specs deterministically. Sorted inputs are required for Test and Score.

Types

type Context

type Context struct {
	// contains filtered or unexported fields
}

Context contains specs to be tested or scored.

func (*Context) Add

func (c *Context) Add(specs ...Spec)

Add adds the specs to the requirement context.

func (*Context) Reset

func (c *Context) Reset()

Reset removes all specs from the context.

func (Context) Score

func (c Context) Score(s2 ...Spec) int64

Score returns an integer match score of c and s2 which can be compared relative to other specs. The exact score is not meaningful alone. Specs in c2 must have been created at once by Parse or sorted using Sort. Currently the loss function used takes 1 point per unmatched optional condition and uses approximate squared error to compare numeric ranges. It is possible to construct a failing spec which is more favorable than A passing spec, but the loss would need to be close to MaxInt64.

func (Context) Test

func (c Context) Test(c2 ...Spec) bool

Test returns whether the c matches c2. c matches c2 when all required specs in c are satisfied by c2. Specs in c2 must have been created at once by Parse or sorted using Sort. See package documentation for more details.

type Spec

type Spec struct {
	Key    []byte
	Value  []byte
	Negate bool
	Prefer bool
	Equal  bool
}

Spec is a parsed requirement expression.

func Parse

func Parse(s ...string) []Spec

Parse parses variadic string requirements from string representations. See package documentation for syntax.

func (Spec) String

func (c Spec) String() string

String returns a requirement expression as a string.

Directories

Path Synopsis
Package requireutil provides utilities for working with serialized requirement expressions.
Package requireutil provides utilities for working with serialized requirement expressions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL