Skip to main content

Posts

Showing posts from 2014

Generalized Multicast Delegates in Pure C#

.NET's delegates are a powerful and convenient abstraction available since .NET 1.1. They encapsulate a method pointer and the object the method belongs to in a single callable "function object". Multicast delegates are an extension of plain delegates, in that they encompass multiple single delegates. Invoking a multicast delegate invokes every encapsulated delegate, in the order they were added. Multicast delegates are key to event handling patterns that were a core part of the CLR nearly since its inception. If you're curious about virtual machines or CLR internals, you've perhaps wondered how multicast delegates actually work. These are the key properties of multicast delegates: They encapsulate a list of delegates of the same delegate type. Adding a delegate returns a new multicast delegate containing the new addition at the end of the list (the original is unchanged). Removing a delegate returns a new multicast delegate without the specified delegate (

Sasa v0.14.0 Released

A quick release, fixing one bug and adding some performance improvements and some new collection types. Here's the changelog: * added a faster and more compact hash array mapped trie under Sasa.Collections.Trie to replace Sasa.Collections.Tree * added Sasa.Collections.FingerTree * added purity attributes throughout Sasa (for .NET 4) * expanded various test suites and documentation * added a persistent vector, Sasa.Collections.Vector * factored out Atomics.BeginRead/BeginWrite read/write protocol so it can be used in more flexible scenarios * Sasa.Dynamics.Type .MaybeMutable is now computed eagerly * added an efficient, mutable union-find data structure * fixed: Uris.UriDecode now handles the incorrect but common UTF16 encoding * moved Sasa.LockSet under Sasa.Concurrency.LockSet The Sasa.Collections.Tree type is no longer available, and is replaced by the faster and more appropriately named Sasa.Collections.Trie. The original tree was actually a trie, and I didn't

Sasa v0.13.0 Released

The latest Sasa release fixes a few bugs with MIME parsing, and adds a few new concurrency features. Here is the online documentation , or a downloadable CHM file from Sourceforge is available alongside the binaries . The binaries are also available via nuget , of course. Here's the changelog: added Sasa.Concurrency.RWLock, a truly slim concurrent read/write lock switched Sasa.Dynamics.PIC to use RWLock switched Sasa.Dynamics.PIC to rely only on arrays for performance reasons Mail message parsing now doesn't use ad-hoc means to extract a body from the attachments added Sasa.Changeable<T> which encapsulates all INotifyPropertyChanged and INotifyPropertyChanging logic with no space overhead fixed an MIME HTML parsing bug fixed regex lexing added more efficient Enums class exposing static properties for various enum properties alternate views inside multipart/related no longer incorrectly dropped added well-behaved standards conforming URI encode/decode to Sasa.Uris added

Immutable Sasa.Collections.Tree vs. System.Collections.Dictionary vs. C5 HashDictionary

I've previously posted about Sasa's hash-array mapped trie, but I never posted any benchmarks. I recently came across this post on Stackoverflow which provided a decent basic benchmark between .NET's default Dictionary<TKey, TValue>, the C5 collection's hash dictionary, F#'s immutable map, and .NET's new immutable collections. I slightly modified the file to remove the bench against the F# map and the new immutable collections since I'm still using VS 2010, and I added a simple warmup phase to ensure the methods have all been JIT compiled and the GC run to avoid introducing noise: static void Warmup() { var x = Tree.Make<string, object>(); var y = new C5.HashDictionary<string, object>(); var z = new Dictionary<string, object>(); z.Add("foo", "bar"); for (var i = 0; i < 100; ++i) { x = x.Add("foo" + i, "bar"); y.Add("foo" + i, "bar&q

A Truly Slim Read/Write Lock in C#

It's pretty well known that the CLR's ReaderWriterLock and ReaderWriterLockSlim have unappealing performance characteristics. Each class also encapsulates signficant state, which precludes its use in fine-grained concurrency across large collections of objects. Enter Sasa.Concurrency.RWLock in the core Sasa assembly. This is the most lightweight R/W lock I could come up with, particularly in terms of resources used. It's a struct that encapsulates a simple integer that stores the number of readers and a flag indicating whether a writer is active. The interface is similar to ReaderWriterLockSlim, although there are a few differences which are needed to keep the encapsulated state so small: public struct RWLock { // this field is the only state needed by RWLock private int flags; public void EnterReadLock(); public void ExitReadLock(); public bool TryEnterReadLock(); public void EnterWriteLock(object sync); public bool TryEnterWriteLock(object sync);

Clavis 1.0.0-alpha2 Released

Stan Drapkin, of SecurityDriven.NET fame, was nice enough to provide a little feedback on the Clavis implementation . He pointed out a possible issue with parameter names not being properly URL-encoded, which this release fixes. I also applied a few minor optimizations so generating URLs should be a little faster. I've been using Clavis in production for a couple of years now, so it's fairly stable and user-friendly. The Clavis wiki and issue tracker are available here .

Clavis Rebooted: Secure, Type-Safe URLs for ASP.NET

A few years ago, I wrote about a web security microframework for ASP.NET which provided a few primitives for secure parameter-passing and navigation. I've just released a public alpha on Nuget for anyone who's willing to try it. The previous article covered the theoretic foundation of Clavis well enough, but it has undergone a few small revisions to make it easier to use and integrate more seamlessly with ASP.NET. This post will serve as an end-user introduction to Clavis, the rationale behind the design decisions, and the benefits it provides. As a brief summary to whet your appetite, here are the advantages that the Clavis library provides for an otherwise standard ASP.NET web forms or MVC project: By default, URLs are derived from types, so the compiler ensures that every page that will be displayed actually exists. The default URL generated can be overridden via an attribute. Declarative specification of the types and number of parameters a page accepts, which the c