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?
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...