Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

Longest Prefix Match #5

Open
phreed opened this issue Nov 29, 2011 · 9 comments
Open

Longest Prefix Match #5

phreed opened this issue Nov 29, 2011 · 9 comments

Comments

@phreed
Copy link

phreed commented Nov 29, 2011

Given a trie with keys 'abc' 'abcde' & 'abcdefgh'
I wish to have a method which when given 'abcdefg'
returns the entry whose key is 'abcde'.
That is the entry whose key is the longest prefix matching the given string.
I have to do a bit of testing but I believe the method already exists.
AbstractPatriciaTrie.getNearestEntryForKey(Object key);
but it is declared package rather than public.

@sergio91pt
Copy link

Its floorEntry(K key) that gives the right answer not getNearestEntryForKey.

Example:
A trie with 'L' and 'LL'.
And you search for 'LD', with floorEntry you get 'L' while getNearestEntryForKey and selectKey return 'LL'.

floorEntry is also package protected but part of the NavigableMap interface.

@megahall
Copy link

megahall commented Mar 8, 2014

Calling that function actually causes a crash, because it modifies the map. Does anybody have another function which is safe to use instead?

@megahall
Copy link

megahall commented Mar 8, 2014

I implemented it like this, but I'm not sure it's right, if somebody can check my work I'm going to see about contributing it to the Apache version.

  public TrieEntry<K,V> getFloor(K key) {    
    int lengthInBits = lengthInBits(key);

    if (lengthInBits == 0) {
      if (!root.isEmpty()) {
        return root;
      } else {
        return null;
      }
    }

    TrieEntry<K, V> found = getNearestEntryForKey(key);
    if (compareKeys(key, found.key)) {
      return found;
    }

    int bitIndex = bitIndex(key, found.key);
    if (Tries.isValidBitIndex(bitIndex) || Tries.isEqualBitKey(bitIndex)) {
      return found;
    } else if (Tries.isNullBitKey(bitIndex)) {
      if (!root.isEmpty()) {
        return root;
      } else {
        return null;
      }
    }

    // we should have exited above.
    throw new IllegalStateException("invalid lookup: " + key);
  }

@sergio91pt
Copy link

That code is definitely not equivalent to floorEntry(K key).

From what I remember using floorEntry didn't cause a crash, but yes it modifies the trie (so its unsafe with concurrent access).

@rkapsi
Copy link
Owner

rkapsi commented Mar 8, 2014

Nice to see that people are using it. We contributed an earlier version/fork to Apache Commons and it got accepted in v4.

http://commons.apache.org/proper/commons-collections/javadocs/api-release/index.html?org/apache/commons/collections4/trie/package-summary.html

If you're looking for a general purpose (Patricia) Trie then I'd look into that.

@megahall
Copy link

I saw that. But I didn't see any methods for longest-prefix match.

On Sat, Mar 8, 2014 at 12:41 PM, Roger Kapsi [email protected]:

Nice to see that people are using it. We contributed an earlier
version/fork to Apache Commons and it got accepted in v4.

http://commons.apache.org/proper/commons-collections/javadocs/api-release/index.html?org/apache/commons/collections4/trie/package-summary.html

If you're looking for a general purpose (Patricia) Trie then I'd look into
that.


Reply to this email directly or view it on GitHubhttps://github.com//issues/5#issuecomment-37109180
.

@raner
Copy link

raner commented Dec 18, 2020

In case anyone else is wondering how to get a longest prefix match with a PatriciaTrie, the methods you are looking for are:

  • public K selectKey(final K key)
  • public V selectValue(final K key)

They are unfortunately only declared on AbstractPatriciaTrie and are not part of the general Trie interface. Also, if the desired prefix is not part of the tree these methods will return "the value whose key is closest in a bitwise XOR metric", i.e. if you are looking for an exact prefix match, you need to also compare the returned key against the search key.

@ivanr
Copy link

ivanr commented Jul 22, 2022

In my tests, floorEntry doesn't return the longest prefix either. For example, if the trie contains com.example. and com., floorEntry("com.google.") returns com.example. rather than com.

EDIT I am talking about the code in Apache Commons (4.1), but from a quick look I think the code is the same.

@alexander-ryabov
Copy link

floorEntry has nothing in common with longest prefix, it can be uses only for initial approximation

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants