114 lines
3.0 KiB
C
114 lines
3.0 KiB
C
/* SPDX-License-Identifier: AGPL-3.0-or-later */
|
|
/* Copyright (C) 2026 David (Corey) Herrera */
|
|
/*
|
|
* rosa.h — Suffix automaton for ROSA (Rapid Online Suffix Automaton)
|
|
*
|
|
* Module prefix: sa_ (suffix automaton)
|
|
*
|
|
* Two variants:
|
|
* 1. sa_automaton — binary alphabet {0,1}
|
|
* 2. sa_token_automaton — large alphabet (vocab-sized), hash-map transitions
|
|
*
|
|
* Properties:
|
|
* - Online: O(1) amortized per symbol
|
|
* - At most 2*N states for sequence of length N
|
|
* - Longest suffix match query: O(1) amortized per step
|
|
*
|
|
* Reference: Blumer et al. (1985), cp-algorithms.com/string/suffix-automaton
|
|
*/
|
|
|
|
#ifndef FOUNDRY_ROSA_H
|
|
#define FOUNDRY_ROSA_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* ================================================================
|
|
* Binary suffix automaton (alphabet = {0, 1})
|
|
* ================================================================ */
|
|
|
|
typedef struct {
|
|
int len;
|
|
int link;
|
|
int endpos;
|
|
int next[2];
|
|
} sa_state;
|
|
|
|
typedef struct {
|
|
sa_state *states;
|
|
int n_states;
|
|
int capacity;
|
|
int last;
|
|
int seq_len;
|
|
} sa_automaton;
|
|
|
|
sa_automaton* sa_new(int initial_cap);
|
|
void sa_free(sa_automaton *sa);
|
|
void sa_reset(sa_automaton *sa);
|
|
void sa_extend(sa_automaton *sa, int symbol, int position);
|
|
int sa_query_step(sa_automaton *sa, int symbol, int *state, int *match_len);
|
|
|
|
/* ================================================================
|
|
* Token-level suffix automaton (large alphabet, hash-map transitions)
|
|
* ================================================================ */
|
|
|
|
typedef struct {
|
|
int key;
|
|
int value;
|
|
} sa_trans_entry;
|
|
|
|
typedef struct {
|
|
int len;
|
|
int link;
|
|
int endpos;
|
|
sa_trans_entry *trans;
|
|
int trans_cap;
|
|
int trans_count;
|
|
} sa_token_state;
|
|
|
|
typedef struct {
|
|
sa_token_state *states;
|
|
int n_states;
|
|
int capacity;
|
|
int last;
|
|
int seq_len;
|
|
int alphabet_size;
|
|
} sa_token_automaton;
|
|
|
|
sa_token_automaton* sa_token_new(int initial_cap, int alphabet_size);
|
|
void sa_token_free(sa_token_automaton *sa);
|
|
void sa_token_reset(sa_token_automaton *sa);
|
|
void sa_token_extend(sa_token_automaton *sa, int token, int position);
|
|
int sa_token_query_step(sa_token_automaton *sa, int token, int *state, int *match_len);
|
|
|
|
/* ================================================================
|
|
* Position map (SA position -> source location)
|
|
* ================================================================ */
|
|
|
|
typedef struct {
|
|
int conv_idx;
|
|
int msg_idx;
|
|
int token_offset;
|
|
} sa_position_info;
|
|
|
|
typedef struct {
|
|
sa_position_info *entries;
|
|
int count;
|
|
int capacity;
|
|
} sa_position_map;
|
|
|
|
sa_position_map* sa_position_map_new(int initial_cap);
|
|
void sa_position_map_free(sa_position_map *map);
|
|
int sa_position_map_append(sa_position_map *map, int conv_idx, int msg_idx, int token_offset);
|
|
const sa_position_info* sa_position_map_get(const sa_position_map *map, int position);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* FOUNDRY_ROSA_H */
|