<commit_before>package baa

import (
	"fmt"
	"sync"
)

const (
	leafKindStatic uint = iota
	leafKindParam
	leafKindWide
)

// Tree provlider router for baa with radix tree
type Tree struct {
	autoHead          bool
	autoTrailingSlash bool
	mu                sync.RWMutex
	groups            []*group
	nodes             [RouteLength]*leaf
	baa               *Baa
	namedNodes        map[string]*Node
}

// Node is struct for named route
type Node struct {
	paramNum int
	pattern  string
	format   string
	root     *Tree
}

// Leaf is a tree node
type leaf struct {
	kind        uint
	pattern     string
	param       string
	handlers    []HandlerFunc
	children    []*leaf
	childrenNum uint
	paramChild  *leaf
	wideChild   *leaf
	parent      *leaf
	root        *Tree
}

// group route
type group struct {
	pattern  string
	handlers []HandlerFunc
}

// NewTree create a router instance
func NewTree(b *Baa) Router {
	t := new(Tree)
	for i := 0; i < len(t.nodes); i++ {
		t.nodes[i] = newLeaf("/", nil, t)
	}
	t.namedNodes = make(map[string]*Node)
	t.groups = make([]*group, 0)
	t.baa = b
	return t
}

// NewNode create a route node
func NewNode(pattern string, root *Tree) *Node {
	return &Node{
		pattern: pattern,
		root:    root,
	}
}

// newLeaf create a tree leaf
func newLeaf(pattern string, handlers []HandlerFunc, root *Tree) *leaf {
	l := new(leaf)
	l.pattern = pattern
	l.handlers = handlers
	l.root = root
	l.kind = leafKindStatic
	l.children = make([]*leaf, 128)
	return l
}

// newGroup create a group router
func newGroup() *group {
	g := new(group)
	g.handlers = make([]HandlerFunc, 0)
	return g
}

// SetAutoHead sets the value who determines whether add HEAD method automatically
// when GET method is added. Combo router will not be affected by this value.
func (t *Tree) SetAutoHead(v bool) {
	t.autoHead = v
}

// SetAutoTrailingSlash optional trailing slash.
func (t *Tree) SetAutoTrailingSlash(v bool) {
	t.autoTrailingSlash = v
}

// Match find matched route and returns handlerss
func (t *Tree) Match(method, pattern string, c *Context) []HandlerFunc {
	var i, l int
	var root, nl *leaf
	root = t.nodes[RouterMethods[method]]
	current := root

	for {
		switch current.kind {
		case leafKindStatic:
			// static route
			l = len(current.pattern)
			if l > len(pattern) {
				break
			}
			i := l - 1
			for ; i >= 0; i-- {
				if current.pattern[i] != pattern[i] {
					break
				}
			}
			if i >= 0 {
				break
			}
			if len(pattern) == l || current.children[pattern[l]] != nil {
				pattern = pattern[l:]
				root = current<commit_msg>fix staitc route not found with same prefix in param route<commit_after>package baa

import (
	"fmt"
	"sync"
)

const (
	leafKindStatic uint = iota
	leafKindParam
	leafKindWide
)

// Tree provlider router for baa with radix tree
type Tree struct {
	autoHead          bool
	autoTrailingSlash bool
	mu                sync.RWMutex
	groups            []*group
	nodes             [RouteLength]*leaf
	baa               *Baa
	namedNodes        map[string]*Node
}

// Node is struct for named route
type Node struct {
	paramNum int
	pattern  string
	format   string
	root     *Tree
}

// Leaf is a tree node
type leaf struct {
	kind        uint
	pattern     string
	param       string
	handlers    []HandlerFunc
	children    []*leaf
	childrenNum uint
	paramChild  *leaf
	wideChild   *leaf
	parent      *leaf
	root        *Tree
}

// group route
type group struct {
	pattern  string
	handlers []HandlerFunc
}

// NewTree create a router instance
func NewTree(b *Baa) Router {
	t := new(Tree)
	for i := 0; i < len(t.nodes); i++ {
		t.nodes[i] = newLeaf("/", nil, t)
	}
	t.namedNodes = make(map[string]*Node)
	t.groups = make([]*group, 0)
	t.baa = b
	return t
}

// NewNode create a route node
func NewNode(pattern string, root *Tree) *Node {
	return &Node{
		pattern: pattern,
		root:    root,
	}
}

// newLeaf create a tree leaf
func newLeaf(pattern string, handlers []HandlerFunc, root *Tree) *leaf {
	l := new(leaf)
	l.pattern = pattern
	l.handlers = handlers
	l.root = root
	l.kind = leafKindStatic
	l.children = make([]*leaf, 128)
	return l
}

// newGroup create a group router
func newGroup() *group {
	g := new(group)
	g.handlers = make([]HandlerFunc, 0)
	return g
}

// SetAutoHead sets the value who determines whether add HEAD method automatically
// when GET method is added. Combo router will not be affected by this value.
func (t *Tree) SetAutoHead(v bool) {
	t.autoHead = v
}

// SetAutoTrailingSlash optional trailing slash.
func (t *Tree) SetAutoTrailingSlash(v bool) {
	t.autoTrailingSlash = v
}

// Match find matched route and returns handlerss
func (t *Tree) Match(method, pattern string, c *Context) []HandlerFunc {
	var i, l int
	var root, nl *leaf
	root = t.nodes[RouterMethods[method]]
	current := root

	for {
		switch current.kind {
		case leafKindStatic:
			// static route
			l = len(current.pattern)
			if l > len(pattern) {
				break
			}
			i := l - 1
			for ; i >= 0; i-- {
				if current.pattern[i] != pattern[i] {
					break
				}
			}
			if i >= 0 {
				break
			}
			if len(pattern) == l || current.children[pattern[l]] != nil ||
				current.paramChild != nil ||
				current.wideChild != nil {
				pattern = pattern[l:]
				root = current
{'fraction_non_alphanumeric': 0.10804597701149425, 'fraction_numerical': 0.0034482758620689655, 'mean_word_length': 2.7696750902527074, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3324115', 'n_tokens_mistral': 1905, 'n_tokens_neox': 1774, 'n_words': 589}