Search code examples
c#url-shortener

Using a Bijective Dictionary in a URL shortener


I am creating a new URL shortener and have read that a Bijective function is what is required. So, I found Jon Skeet's BiDictionary (excellent) and wondered how I'd use this within the URL shortener application. Currently, I Base36 encode the database ID column to create my shortened URL and store the full URL into the table. This works fine but I'm lost as to why I need to use a Bijective function? Do I store the values from the database into the Bijective Dictionary? Is what I currently have functional enough? What would the benefits be of using a Bijective Dictionary?


Solution

  • Not really sure that I understand you question fully...

    If I understand you correctly you have created a lookup table with a unique ID and a URL. Your shortened URL is the Base36 encoded ID.

    Let's look at the use cases:

    • Create a shortened URL
      means in you implementation check whether you already have that URL in the table (simple, just return the Base36 encoded ID).
      Otherwise just create a new entry and return the Base36 encoding of the new ID.

    • Lookup the full URL
      Decode the Base36 value to an ID, lookup the ID in the table and return -if found- the full URL.

    So basically you have created a bijective function (a bidirectional 1:1 correspondence) - just something that works in both directions without any loss, thus fully invertible regarding the given URLs in your table. The Base36 encoding/decoding is fully invertible too so that is a bijective function too :-)

    The BiDictionary from Jon you mention would be good base for an in-memory-cache (recommend write-through) so you can avoid the DB roundtrip where possible. The Bidictionary uses Dictionary while for a cache which can be accessed by multiple threads I would strongly recommend using ConcurrentDictionary . In your case the List<> part from Jon's implementation is not needed since you always would have a 1:1 correspondence. For faster lookup you could use the Base36 encoded value as a key...