Many years ago, when I actually paid attention to such things, I rejected MySQL in favor of PostgreSQL because of the former’s terrible defaults (e.g. no ACID guarantees on the default storage engine at the time, MyISAM) and missing features (in 3.23, no subqueries, stored procedures, views, etc.). The only time I regretted it was when dealing with other software that required MySQL and would not work with PostgreSQL.
I have a copy of every single email I’ve sent or received at work since mid-2003. Here is a chart of the number of work emails I send and receive per year.
I recently helped introduce a Varnish cluster at work to offload a significant number of requests from a heavily-trafficked internal web service. This Varnish cluster serves approximately 10,000 requests/second (with peaks in the 20-30,000 requests/second range) 24x7x365.
While working on this project I ran into a few interesting problems with Varnish. The most interesting one I saw was that Varnish would consume more and more RAM until eventually it would consume all the memory on the box and crash. Using varnishstat, we diagnosed that this was due to unbounded growth of transient storage within the Varnish process.
A reader-writer lock is a lock which will allow multiple concurrent readers but only one writer. A reader-writer lock can be significantly more efficient than a standard mutex if reads on your shared memory far outnumber writes.
Reader-writer locks naturally fit together with caches, as caches are only effective if reads far outnumber writes.
Here is a general pattern for using a reader-writer lock with a cache:
Acquire a reader lock.
Check the cache for the value. If it exists, save the value and go to step 8.
Upgrade the reader lock to a writer lock.
Check the cache for the value. If it exists, save the value and go to step 7.
Calculate the value (expensive, otherwise we wouldn’t cache it)
Insert the value into the cache.
Release the writer lock.
Release the reader lock.
Return the value.
The reason why we have to check the cache for the value again in step (4) is because of the following possibility (assume step 4 doesn’t exist):
When you are processing an HTTP request in ASP.NET you can retrieve the user-provided query string parameters using the HttpRequest.QueryString property. This property is an instance of the NameValueCollection class.
If the user has provided multiple parameters with the same key in the query string, HttpRequest.QueryString[key] will return all the values concatenated together with commas. If you would rather process the values individually, use HttpRequest.QueryString.GetValues(key), which will return an array of all the provided values.
In the Windows XP login screen, the password text box will warn you with a balloon tooltip if you accidentally turn Caps Lock on. The balloon tooltip appears to be a Windows tooltip common control with the TTS_BALLOON style.
To replicate this functionality, I decided to write a function called ShowMsgBalloon() which, given a control and the various balloon tooltip parameters, creates and shows the balloon tooltip below the control.