views:

116

answers:

2

I've created a new class that inherits from SortedDictionary:

public partial class ListIncomeWeight : SortedDictionary<string, double> { 
    public Guid Identity { get; set; }
}

This list is combined with a few dozens of other lists, where the other lists will keep track if they already calculated with this list or not. For that purpose, they use a Dictionary to store the result if it was calculated before.

The logic behind the Identity is that it will uniquely identify the list when it's used in some other calculation. This way, when I am repeating a calculation, I check the GUID first to see if I've calculated it before. If so, I already know the result of this calculation and can save some time by not having to loop through this list again. (The calculations are complex and I need to do a lot of them, so even though it's a small reduction per calculation, it's a real time-saver.)

However, what happens when I create the list, add some items, calculate, add some more items and calculate again? In that case, I won't get the expected result because the calculation never used the new items. So I need to work around this.

My idea is simple: change the GUID whenever an item is added or removed. Of course I could override the Add/Remove methods but I want something more generic. Is there some delegate or event which I can use to respond to changes in this list?


Some further explanations... I have two sets of lists. One set of lists contains an overview on how much someone earns. (Salary, provision, interest, interest from saving accounts, etc.) The second set of lists defines a weight factor for every type of income. It's a rule set which tells me that salary counts as 100% but provision only for 75%, etc. These weight-lists will add everything after applying the weight factor, resulting in a final amount.

I have to deal with income from a person and their partner, plus income before and after retirement. Plus income that doesn't depend on retirement. Thus, I have about 6 lists of income per person.

I also have several dozens of weight lists. These are used by about 1600 different products and the worst-case scenario is that I have to do half a million calculations. I need to reduce this number, thus I need lots of optimizations. This is just part of these optimizations.

In general, I need to combine the lists of incomes with the lists of weights which results in a couple of values. One of them is used for a lookup, another one to calculate how much a person can spend per year on costs for the product and yet another one is a correction to this amount. And there are a few more income/weight combinations that I need to take into the equation, but in general this depends on the calculation itself. The calculation also uses an interest rate, which varies quite a lot, although it tends to be in a short range. I've already optimized that part by just calculating for distinct interest rates. But now I want to reduce the number of calculations needed to calculate these weighted incomes. With any luck, I should be able to reduce the number of calculations from half a million to just a few thousands, possibly even less.

Which is why I want to know if the values in this weight list have been added or removed. When this happens, it becomes a different list, thus it needs a different GUID. I'm working on a generic class library and don't have much control over how it's going to be used, so I need to make sure the other developers can't use it in some wrong way. Which is why this functionality would be real useful.

+1  A: 

I don't think there is any generic way to get callbacks on change.

On the other hand I got lost with your logic - you use a GUID to identify a unique calculation, but then you kind of change this calculation (change the dictionary with results)? Wouldn't it be easier to create a copy of the dictionary with a new GUID when you add new items? (sorry, I don't really understand how it works)

Grzenio
Added some more text to the Q. But basically, I have two sets of lists and I need to combine any list from set A with any list from set B and remember this result in list B.
Workshop Alex
Adding a copy of the list when I add a value would be possible. Unfortunately, the values are always added one by one thus I could end up with a huge list of similar copies. (Yeah, what makes it complex are the lists within lists within lists...)
Workshop Alex
+1  A: 

Hello,

I think you have to rewrite even a little bit your ListIncomeWeight class by updating the Guid when the list changes (Add, Remove, Clear). I've set a flag that tells the inner list changed or not. Identity property is updated based on this flag. Why not also create an event for this: Changed

public partial class ListIncomeWeight : SortedDictionary<string, double>
{
    public delegate void ChangedHandler();
    public event ChangedHandler Changed;

    private Guid _guid;
    private bool _changed = false;

    private void RaiseChanged()
    {
        _changed = true;
        if (Changed != null) Changed();
    }

    public new void Add(string key, double value)
    {
        base.Add(key, value);
        RaiseChanged();
    }

    public new void Clear()
    {
        base.Clear();
        RaiseChanged();
    }

    public new bool Remove(string key)
    {            
        bool res = base.Remove(key);

        RaiseChanged();

        return res;
    }

    public Guid Identity
    {
        get
        {
            if (_changed)
            {
                _guid = new Guid();
                _changed = false;
            }
            return _guid;
        }
        set {
            _guid = value;
        }
    }        
}
najmeddine
Yeah, this happens to be my alternate solution...
Workshop Alex