Using a Bijective Dictionary in a URL shortener - c#

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

Related

Dictionary list or file access methods or any other method in C#

I have a text file which follows exactly the same type:
**Unique-Key_1**
Value1
Value2
**Unique-Key_2**
Value1
**Unique_Key_3**
Value1
(Please note that the keys and values are not fixed.They might grow in time but one thing is confirmed: It will always follow this structure)
My program wants to search for a key and then retrive all values under it.
I have some viable solutions for this.
1) Should I use a dictionary type and then when my app loads read all keys and values and populate that list?
2) Can I use file access/search methods during run-time and based upon a key , search it and then retrieve values ?
3) Which is the optimum method or is there any methods or any other ways to achieve the same ?
Things to consider:
Does the application have time to load in and parse the file before data is searched? If so, consider parsing the file into a Dictionary. If not, parse the file as needed.
Will the file be very large? If so, parsing it into a Dictionary may take up too much memory. Consider an LRU Cache like Object cache for C#.
Are the keys in the file sorted? If so, a binary search on the file may be possible to speed up the file parses.
Does the data change frequently? If so, parsing the file would guarantee the data is up to date at the cost of slower data access.
Another alternative is to load the values into database tables or a key/value store. This allows the data to be updated piece meal or completely with reasonable access speed if needed at the expense of maintaining and running the database.
Okay, if the file isn't that large I would recommend the Dictionary approach because it's going to make accessing it easier and more efficient at runtime. However, if the file is too large to hold in memory you can use the algorithm provided in this answer to search it.

Retrieving image stored in long datatype

I have one web application, having one table in oracle10g having following structure:
Column Name DataType
UserImage long
My problem is that how should I display the IMAGE on my aspx page which is stored in long format?
If data type is BLOB or CLOB then it could be easier one, but it's stored in long.
I could not change the datatype since this is third party DB.
Please suggest me how could I achieve this. The solution could be either using Oracle or C#, I'm fine with both.
Thanks in advance.
You can't store an image in a 'long' datatype.
Instead - hold a static list of key-value pairs, each pair defines an index (say, from 1 to n) of an image
and the value holds the Image's file name.
For instance, the following pseudo code demonstrates a similar approach (should be implemented on the client/server side of your application, not in the DB
SWITCH (USERIMAGE)
CASE 1:
SETIMAGE("IMAGES/IMAGE_NUMBER_ONE.JPG");
BREAK:
CASE 2:
SETIMAGE("IMAGES/IMAGE_NUMBER_TWO.JPG");
BREAK:
and so on.
Another solution:
Assume your 1st table is called "Table1". create a new table in your database called my_images
Column name Column type Comments
UserImage LONG Foreign key to Table1.UserImage
ImageData BLOB
And,
SELECT t1.ImageData FROM Table1 t1, my_images mi
WHERE t1.UserImage == mi.UserImage;
The "chunk" characters you have posted seem to be a TIFF image. That gives an idea how the images are stored. In fact, the binary image data seems to be stored as character data. That's certainly completely unsupported and very fragile. I'd recommend converting it as soon as possible.
In the mean time, I can propose two ways of retrieving the data so I cannot guarantee that either one works.
But approaches are susceptible to characters sets: If two or more character sets are involved, your data will be converted and thereby destroyed. And both are susceptible to the maximum length of certain data types.
Approach 1:
Try to go via the RAW data type and retrieve it as a byte array. It's certainly limited to 32'000 characters, maybe even less.
SELECT UTL_RAW.CAST_TO_RAW(UserImage) FROM UNNAMED_TABLE WHERE ...
On the C# side, you should get an OracleBinary or byte[] instance.
Approach 2:
Try to retrieve it as a string. Then convert the string into a byte array using the original encoding (Encoding.GetBytes. With enough luck, the original data can be restored.

ASP.NET MVC / C# - String to valid URL characters?

I don't know how to ask this, and I don't know what it is called either so I'll just describe what I want to achieve.
In the database, some articles' title originaly has spaces:
my title with spaces
But in the url, spaces are replaced by other characters such as plus sign (+) or underscore (_)
http://www.mydomain.com/mycontroller/myaction/my_title_with_spaces
or
http://www.mydomain.com/mycontroller/myaction/my+title+with+spaces
Now, how do you do that in C#? Or is there any helper in ASP.NET MVC that can do something like that?
Let say we achieved the said URL, is there any risk that two unique titles become the same in the URL? Please consider these titles:
Title's
Titles
after parsing, they became the same
Titles
Titles
This will be a problem when retrieving the article from the database since I'll get two results, one for "Title" and one for "Title's".
I would implement that functionality like this:
1. When creating a new article, generate the URL representation based on the title.
Use a function that converts the title for a suitable representation.
For example, the title "This is an example" might generate something like "This_is_an_example".
This is up to you. You can create a function that parses the title with rules you define, or use an existing one if it suits better your problem.
2. Ensure the URL representation is unique
If it's going to be an ID, it must be unique. So, when creating new articles you must query your database for the resulting URL representation. If you get a result from the database, it means the newly created article generated the same representation as one of the already created articles. Add something to it so it remains unique.
This could be something like "This_is_an_example_2". In this case, we added the "_2" to the end of the generated representation so it differs from the already existing one. Once more, with each change you have to ensure this representation remains unique.
3. Save the created ID in the database, along with the article data
In the database be sure to save the "This_is_an_example" ID and relate it to the article. Maybe even as the table primary key?
4. Query the database for the correct article
Now, about showing a site visitor the correct article:
When a visitor asks for the following resource, for example:
http://www.mydomain.com/mycontroller/myaction/this_is_an_example_2
Extract the URL part that identifies the article, in this case "this_is_an_example_2".
When you have that, you have the identifier of the article in the database. So, you can query the database for the article with the "this_is_an_example_2" ID and show the article's content to the user.
This might involve some URL rewriting. Unfortunately I'm unable to help you with that in asp.NET. Some search on the subject will surely help you.

.Net to SQL, best way to compare unique values

i have an import process, where i take a CSV file in .Net, and it writes to two user tables, in the DataBase. It's a pretty complex process, it takes several minutes to process about five hundred users at at time.
In that process, i need to generate a string, random string, that will be unique to each user, as it gives him access to some promotions. I can't use GUIDs because it has to be a simple string for the user to input in a splash screen.
What I need to know is, what is the best way to check if each newly generated key doesn't repeat any already created in thousands of pre-existing users.
I don't want to add a new query in each inserted row, asking if the string is already there.
Thanks, i hope i was clear enough
How many users are there compared to the number of possible unique keys?
If there are many more possible keys than there are users then I'd just add a unique constraint on the key column, and generate a new key if you hit a constraint violation.
If you're likely to get a lot of collisions with the above technique then there are a few options open to you:
Pre-generate sets of unique keys, store them in a table somewhere and take one when needed.
Add some uniqueness to the keys: do the users have a unique id that could be incorporated?
You can store string in Dictionary in Key value. If string is repeated then it will generate an error, here you can handle error and generate new string for user.
Hope it will help for you.
One simple way could be to use part of an MD5 for the customer + the customerid encoded in hex.
The customerid part ensures uniqueness and the MD5 part ensures that you cannot guess another users key.
Depending on how short string you can handle you can use just the first 6-10 chars from the MD5 and if you need to shorten it further reencode using somthing more compact than Hex, like base-64 or if you cannot handle different case make your own selection, A-Z + 0-9 and maybe some special chars to get an exponent of 2 that is easy to map to hex.

C# : Using hashtables to store two of the same value. Is it possible?

I'm fairly new to programming C# and I have written a program that uses hashtables to store data (in my case, the users name, and if they are "Ready" or "Not Ready". I have 2 tables in total. The first table has the key as the username and the IP address of the client in the value box. the second table has the Ready/Not Ready status (given by a combo box) for the key, and the IP address as the value.
The first table isn't a problem, as I don't want the users name to re-occur. However, in the second table I need the Ready/Not Ready status to re-occur many times. However this does not work as it says there is already a key called "Ready" in the hashtable. Is there nay way to get around this?
You could use a Dictionary<Status,HashSet<IP>> for the second table. This has the additional advantage that inserting/removing an IP is fast since it's a key into the HashSet.
So, the reason for the second hashtable is to quickly look up who is ready or not, correct?
In that case, consider splitting that up into 2 different collections: one for those who are ready, and one for those who are not.
Most likely, a simple List<T> will be fine here, since you just need to see who is in there, rather than finding a specific one (because if you want to do that, you could just look in the other hashtable). If it's important to have similar lookup properties to the hashtable, you can use a HashSet<T> instead, but it depends on your needs.
Keys have to be unique. If you tried to access a value by the key how would it know which one you really wanted?
It sounds like Hashtable is probably not the ideal data structure for your problem.
Keys within a hashtable / dictionary must be unique, so no, you can't technically store two entries in a hash table that share the exact same key.
Also, you should probably use a Dictionary<TKey, TValue) instead of the actual Hashtable type, as it has better performance characteristics.
You can simulate what you want by doing something like creating a Dictionary whose value is a set of some kind:
// Map containing two sets of IP addresses: those that are ready,
// and those that are not ready.
var readyMap = new Dictionary<bool, HashSet<string>>();
readyMap[true] = new HashSet<string>();
readyMap[false] = new HashSet<string>();
// Add an IP address that is ready.
readyMap[true].Add(ipAddress1);
// Add an IP address that is not ready.
readyMap[false].Add(ipAddress2);
However, that might not be the ideal solution. What is the actual problem you are trying to solve?
Okay, I have finally figured this out. I have 3 tables. First one is Key: Username Value: IP. Second is Key: IP Value: Username. Third is Key:Username Value: Ready/Not Ready. Then I simply reference htReady.Value (the hashtable). My whole code is here: http://pastebin.com/Z60GEjK8 .The parts you want to be looking at are the start of Class ChatServer, AddUser, RemoveUser and AcceptClient.
I am new to this, so If you could suggest a better way, I'm all ears.

Categories

Resources