# PSMatcher

A pub/sub matcher algorithm implementation that efficiently matches events against subscriptions.

## Overview

PSMatcher is a Rust library that provides an efficient algorithm for matching events against subscriptions in a publish/subscribe system. The algorithm pre-processes subscriptions into a matching tree for optimized event matching.

Key features:
- Efficient matching using a tree-based algorithm
- Support for complex subscription predicates
- Flexible event attribute system
- Optimized for high-throughput event processing
- Support for regex pattern matching with compiled regex objects

## Concepts

### Events

Events are messages that contain a set of attributes. Each event must have at least one string attribute called "topic". Events can be matched against subscriptions to determine which subscribers should receive the event.

### Subscriptions

Subscriptions are expressions that define which events a subscriber is interested in. In PSMatcher, subscriptions are represented as conjunctions of elementary predicates (combined with AND logic).

### Elementary Predicates

Elementary predicates are the building blocks of subscriptions. Each predicate represents the result of an elementary test on an event attribute. For example, a predicate might test if the "topic" attribute equals "weather".

### Matching Tree

The matching tree is a data structure that efficiently organizes subscriptions for fast event matching. The tree is built during pre-processing and optimized for quick traversal during event matching.

## Implementation

The matching algorithm is based on the tree-based approach described in:

Marcos K. Aguilera, Robert E. Strom, Daniel C. Sturman, Mark Astley, and Tushar D. Chandra. 1999.
Matching events in a content-based subscription system. In Proceedings of the eighteenth annual
ACM symposium on Principles of distributed computing (PODC '99). Association for Computing Machinery,
New York, NY, USA, 53–61. <https://doi.org/10.1145/301308.301326>

## Usage

> **Note:** All code examples in this README are tested as part of the crate's documentation tests.

```rust
use psmatcher::{Matcher, Subscription, ElementaryPredicate, ElementaryTest};
use psmatcher::event_types::{DefaultEvent, AttributeValue};

// Create a matcher
let mut matcher = Matcher::new();

// Create a subscription for weather updates in San Francisco
let subscription = Subscription::new("weather-sf".to_string())
    .with_predicate(ElementaryPredicate::new(
        ElementaryTest::Equals {
            attribute: "topic".to_string(),
            value: AttributeValue::String("weather".to_string()),
        },
        false,
    ))
    .with_predicate(ElementaryPredicate::new(
        ElementaryTest::Equals {
            attribute: "city".to_string(),
            value: AttributeValue::String("San Francisco".to_string()),
        },
        false,
    ));

// Add the subscription to the matcher
matcher.add_subscription(subscription);

// Create a subscription using regex pattern matching
let regex_subscription = Subscription::new("california-cities".to_string())
    .with_predicate(ElementaryPredicate::new(
        ElementaryTest::regex("topic".to_string(), "weather|forecast").unwrap(),
        false,
    ))
    .with_predicate(ElementaryPredicate::new(
        ElementaryTest::regex("city".to_string(), "San (Francisco|Jose|Diego)").unwrap(),
        false,
    ));

// Add the regex subscription to the matcher
matcher.add_subscription(regex_subscription);

// Create an event
let event = DefaultEvent::new("weather".to_string())
    .with_attribute("city".to_string(), AttributeValue::String("San Francisco".to_string()))
    .with_attribute("temperature".to_string(), AttributeValue::Float(72.5));

// Match the event against subscriptions
let matches = matcher.match_event(&event).unwrap();

// Check if our subscriptions matched
assert!(matches.contains("weather-sf"));
assert!(matches.contains("california-cities"));
```

## License

This project is licensed under the Apache License, Version 2.0. 