Makes node prioritization insertion-independent

The order in which nodes were inserted into a tree might produce
failures in lookup mechanism.

    tree = Radix::Tree(Symbol).new
    tree.add "/one/:id", :one
    tree.add "/one-longer/:id", :two

    result = tree.find "/one-longer/10"

    # expected `true`
    result.found? # => false

In above example, reversing the order of insertion solved the issue,
but exposed the naive sorting/prioritization mechanism used.

This change improves that by properly identifying the kind of node
being evaluated and compared against others of the same kind.

It is now possible to know in advance if a node contains an special
condition (named parameter or globbing) or is a normal one:

    node = Radix::Node(Nil).new("a")
    node.normal? # => true

    node = Radix::Node(Nil).new(":query")
    node.named? # => true

    node = Radix::Node(Nil).new("*filepath")
    node.glob? # => true

Which helps out with prioritization of nodes:

- A normal node ranks higher than a named one
- A named node ranks higher than a glob one
- On two of same kind, ranks are based on priority

With this change in place, above example works as expected:

    tree = Radix::Tree(Symbol).new
    tree.add "/one/:id", :one
    tree.add "/one-longer/:id", :two

    result = tree.find "/one-longer/10"

    result.found? # => true

Fixes #18
This commit is contained in:
Luis Lavena 2017-02-04 12:10:51 -03:00
parent 0dc6e174d2
commit 1764332123
4 changed files with 187 additions and 68 deletions

View file

@ -544,6 +544,19 @@ module Radix
result.payload.should eq(:featured)
end
end
context "dealing with named parameters and shared key" do
it "finds matching path" do
tree = Tree(Symbol).new
tree.add "/one/:id", :one
tree.add "/one-longer/:id", :two
result = tree.find "/one-longer/10"
result.found?.should be_true
result.key.should eq("/one-longer/:id")
result.params["id"].should eq("10")
end
end
end
end
end