Treemap Maker

So I’ve added a new little utility to the web site.  Its under the default software page, not one of the sub-pages.

This utility is a bit like Sequoia View, but not actually as good right now.  Only advantage it has over Sequoia is that it can do file count based layout as well as file size based layout.  I find this of interest when backing up a system as the raw file count can often slow down the process as much as large data, so this lets me target where to trim/create archives.

It has left click to zoom in one level (even down to the one file taking up your entire screen level) and right click to undo a zoom.  The layout algorithm is one I found on-line, something called Pivot-by-Middle. does a decent job and wasn’t too complex to implement.  It has a black rectangle to indicate the top-level directory your mouse is currently over, which is very expensive to draw in the current implementation, so it will lag behind if you have a large number of rectangles in the window.  It also shows whatever file your mouse is over up the top.

The colouring is one of the big steps backwards compared to Sequoia – I use a random colour blending approach, where the colour of a square is the blending of the colour of the file and all of its parent directories, and all colours are initialized at random.  Its better than nothing, but that is about all I can say for it…

Caveats: It ignores all errors while trying to walk the file/directory hierarchy – so if you don’t have read access to a large directory, it won’t tell you (it won’t know) and your graph may not be as interesting as it first appears.

Expression is Interesting

I was playing about with Expression trees today for practically the first time and I wrote something like this.

object a = objectDictionary["somekey"];
Expression constExpr = Expression.Constant(a);

Eventually this expression went into a bunch more expressions and finally compiled into a delegate.

It wasn’t until afterwards that I went… wait… what?  I had just passed a reference type to be a ‘constant’ in a delegate and it wasn’t even a string.  Surely it will fail when I run it.  But no, it works just fine.

I may not have written a lot of IL, but I did write a parser for the output of ildasm, so I like to pretend that I know a bit about what you can do in IL and I certainly couldn’t see any way you could embed a reference into some IL.  And it certainly can’t be capturing a, since that rewrites the parent method and Expressions can’t do that…

So I turned to the trusty internet and found ILVisualizer, which I suspect I will be keeping on hand at all times from now on… and lo, the compiled delegate is closed, with the this parameter bound to an instance of CompilerServices.Closure. This type has an object array property called Constants, where my trusty reference has been stored and the generated delegate loads this and accesses the first element.

In part what I find interesting about this is that you can’t trivially write a lambda to do the same thing, since that will capture the variable, and subsequent changes will affect the lambda.  Here we are guaranteed to get the value of the reference at the point in time the expression is constructed.

BindingList does not scale…

So I’ve been doing some UI work in the last 6 months or so – experimenting with MVVM and the like.  Mostly with WPF, but also some win forms.

Until the last few days I had managed to avoid working with BindingList, for one reason or another.  Either because I was using ObservableCollection in WPF or because my lists were static, or they always updated in bulk.  As part of my investigation into BindingList I found that it supports something which ObservableCollection does not. That is, cascade notification of changes to elements.  So if an element type supports INotifyPropertyChanged, then BindingList will raise events when an element raises its PropertyChanged event, saying which element changed and more specifically which property on that element changed.  Seems like a kind of nifty feature, at first glance…

But the implementation does not scale, it is slow, it performs terribly with larger lists.  If your element type supports INotifyPropertyChanged, every time one of those elements raises the property changed event the entire list is walked to work out the index in the list of the item which raised the event!  I was in shock when I first realised this.  You see BindingList is truly just a rather thin wrapper over Collection<T>, so there is no metadata associated with each entry, all of the binding of the element PropertyChanged event is directed to a single handler, and all it gets given is the source and the name of the changed property, so there is no way to include the NewIndex parameter in ListChangedEventArgs without doing a search.  (By default this search even uses the default object comparator, so if you happen to have two different but sometimes equal objects in your list, enjoy the results…)

Another side note – AddNew, the other feature which BindingList has which Collection<T> does not – also does not scale.  It has to use IndexOf to find out where in the list the newly added item ended up  in case it needs to cancel the add, because it supports auto sorting in derived types. (BindingList does not support auto sorting itself…)

Morale of the story… don’t use BindingList for more than a hundred or so items which support INotifyPropertyChanged – write your own.  If you do write your own, consider just not supporting the cascading modify events at all (even though you can do it efficiently if you have to).  Item presentation should bind to the items, not to the list which holds them.  But alas, not every control agrees…

(PS – BindingSource internally creates a BindingList in many scenarios…)

(PPS – Heh, I just realized this is immediately after my Contains rant, and is effectively an IndexOf rant, which I said I hadn’t seen misused much…)