# Changelog

## Refactoring and breaking changes

The merge ending in commit 15c11469fc403495d9364f3dafec85a032e1bbb9 on
October 16, 2020 introduced breaking changes and a major refactoring
of the VMOD. The highlights are:

- Set initialization in `vcl_init` requires that the `.compile()`
  method is invoked after all of the strings are added. This matches
  the idiom of VMOD re2.

- Some error conditions now invoke VCL failure, whereas previously
  methods returned a "distinguished error" value (such as NULL for a
  backend or string), which meant that incorrect usages could go
  undetected.

- Some means have been added to safeguard against VCL failure.

- Methods that retrieve data from the set now have the `element`
  parameter, which makes it possible to use sets as associative
  arrays (lookup by string).

- The implementations of the `.match()` and `.hasprefix()` methods
  have been refactored, and are considerably faster.

In detail:

### Changed

- `.compile()` is now required in `vcl_init` after adding all strings
  to the set.

- Methods that have the `n` parameter invoke VCL failure if `n` is
  greater than the number of strings in the set. This affects:
  `.matched()`, `.element()`, `.string()`, `.integer()`, `.backend()`,
  `.re_match()` and `.sub()`.

- Methods with the `select` parameter invoke VCL failure when `select`
  is used, and:

  - There was no prior invocation of `.match()` or `hasprefix()`.

  - The previous invocation of `.match()` or `.hasprefix()` failed
    (returned false).

  - `select=UNIQUE` and the previous invocation had more than one
    match.

  - `select=EXACT` and the previous invocation had no exact match.

  - But `.matched()` does *not* invoke VCL failure if `select=UNIQUE`
    or `EXACT` is specified, but their criteria are not
    met. `matched()` just returns `false` in such cases. This makes it
    possible to avoid VCL failure for subsequent uses of the two
    enums.

  Affects: `.matched()`, `.which()`, `.element()`, `.string()`,
  `.integer()`, `.backend()`, `.re_match()` and `.sub()`.

- `.match()` and `.hasprefix()` invoke VCL failure if no strings
  were added to the set.

- `.nmatches()` invokes VCL failure if there was no previous
  invocation of `.match()` or `.hasprefix()` in the same task scope.

- The internal PT implementation (patricia trie), which was used for
  both of `.match()` and `.hasprefix()`, has been replaced with PH
  (perfect hash) for `.match()` and QP (quadbit patricia) for
  `hasprefix()`.

- The implementation-specific stats counters have been replaced. See
  [STATISTICS.md](STATISTICS.md).

### Added

- `.compile()`

- The `allow_overlaps` flag in the set constructor. If set to `false`,
  then VCL load fails if there are strings in the set with common
  prefixes. This is meant to ensure that `select=UNIQUE` can always be
  used safely, for use cases in which common prefixes should not ever
  exist.

- The `element` parameter, for lookups by string. Affects:
  `.matched()`, `.which()`, `.string()`, `.integer()`, `.backend()`,
  `.re_match()` and `.sub()`.

- Benchmark code and test data for PH and QP, see the
  [README](src/tests/bench/README.md).

### Removed

The undocumented `.debug()` method.
