1

For a small project on processor affinity, I want to create a simpler method than just a bunch of if(lvProcessors.Items[0].Checked == true && lvProcessors.Items[1] == true etc) comparing their exact values to see which code needs to be transferred to an (IntPtr).

To make the code slightly more efficiënt, I would like to compare an array containing booleans, to at least 14 other arrays containing booleans.

Example code:

        var CheckState = new[] { lvProcessors.Items[0].Checked, lvProcessors.Items[1].Checked, lvProcessors.Items[2].Checked, lvProcessors.Items[3].Checked };
        //setcore1 == 1, setcore2 == 2, etc
        var SetCore1 = new[] { true, false,false,false };
        var SetCore2 = new[] { true, true, false, false };
        var SetCore3 = new[] { false, true, false, false };
        var SetCore4 = new[] { true, false, true, false };
        var SetCore5 = new[] { false, true, true, false };
        var SetCore6 = new[] { true, true, true, false };
        var SetCore7 = new[] { false, false, false, true };
        var SetCore8 = new[] { true, false, false, true };
        var SetCore9 = new[] { false, true, false, true };
        var SetCore10 = new[] { true, true, false, true };
        var SetCore11 = new[] { false, false, true, true };
        var SetCore12 = new[] { true, false, true, true };
        var SetCore13 = new[] { false, true, true, true };
        var SetCore14 = new[] { true, true, true, true };
        int switchcounter = 1;

        switch (switchcounter)
        {
            case 15:
                break;
            default:

                if (Enumerable.SequenceEqual(CheckState,<insertdynamicarrayname))
                {
                    AffinityState = (IntPtr)switchcounter;
                }
                else
                {
                    switchcounter++;
                    goto default;
                }
                break;
        }

So if the first checkbox in the listview lvProcessors is checked, the var CheckState will generate an array containing { true, false,false,false }

This in turn must be compared to one of the SetCore arrays, and will in this case cause a match with SetCore1.

So what I would like to know is; how can I create a dynamic arrayname, based on the switchcounter on the code, that will fuse "SetCore" and switchcounter.ToString(), thus creating SetCore1, SetCore2, SetCore3, etc.

[EDIT]

As suggested by @Luaan, I've implemented his code to what I would've like it to be:

        var SetCore1 = new[] { true, false, false, false};
        [..]
        var SetCore15 = new[] { true, true, true, true };
        var allSets = new [] { SetCore1, SetCore2, SetCore3,SetCore4,SetCore5,SetCore6,SetCore7,SetCore8,SetCore9,SetCore10,SetCore11,SetCore12,SetCore13,SetCore14,SetCore15 };

        foreach (var set in allSets)
        {
            MessageBox.Show(counter.ToString());
            if (Enumerable.SequenceEqual(set, CheckState))
            {
                AffinityState = (IntPtr)counter;
                break;
            }
            else if (Enumerable.SequenceEqual(set, CheckState) == false) 
            {
                counter++;
            }
        }
        EditProcess.ProcessorAffinity = (IntPtr)AffinityState;

In this code, depending on the input of the listviewcheckboxes, it will match the depending result to a SetCore and using the counter it will give the proper int which is converted at the end of the foreach loop and set the very specific cores(i.e. 1, 2 or 0, 2, 3, etc) to be used for the selected process which has been selected earlier in the code(not visible).

Thanks for the suggestion on bitmasks, they look useful, but currently I have no idea how to implement them without taking half my application apart.

BRO_THOM
  • 824
  • 9
  • 24
  • A [bitmask](http://stackoverflow.com/questions/3261451/using-a-bitmask-in-c-sharp) is often a more flexible way of storing boolean combinations. – Alex K. Jul 27 '15 at 14:29
  • Have you tried using a 2-dimensional array? – Graham Jul 27 '15 at 14:53

1 Answers1

0

Just make an array of arrays:

var allSets = new [][] { SetCore1, SetCore2, SetCore3, ... }

Then you can use a simple for cycle:

for (var i = 0; i < allSets.Length; i++)
   HandleSet(allSets[i]);

Using Enumerable.SequenceEqual is going to be a bit slow. If you care about performance (I don't think you necessarily do in a case like this), have a look at BitArray - it's much smaller in memory, and the match is mostly a simple bitmasking.

EDIT:

If you want to convert between a bool[] and int (or byte, whatever you need), you can use something like this:

public bool[] ToBoolArray(int val)
{
  var bits = new bool[sizeof(int) * 8];

  for (var i = 0; i < bits.Length; i++)
  {
    bits[i] = (val & (1 << i)) > 0;
  }

  return bits;
}

public int ToInt32(bool[] bits)
{
  var output = default(int);

  for (var i = 0; i < bits.Length; i++)
  {
    output |= bits[i] ? 1 << i : 0;
  }

  return output;
}

This avoids having to deal with tons of annoying strings. Using a BitArray this is even simpler - creating a BitArray from int is trivial (there's a constructor), and changing it back to int can be done easily as above, just use bits.Get(i) instead of bits[i].

Or even better, make your own class for handling this:

public sealed class CpuMask
{
  private int _bits;

  public bool this[int index]
  {
    get { return (_bits & (1 << index)) > 0; }
    set { if (value) _bits |= (1 << index); else _bits &= ~(1 << index); }
  }

  public CpuMask(int mask)
  {
    _bits = mask;
  }

  public CpuMask(IntPtr mask) : this(mask.ToInt32()) { }

  public IntPtr ToIntPtr() { return new IntPtr(_bits); }
}
Luaan
  • 62,244
  • 7
  • 97
  • 116
  • This was actually what I was looking for, the problem is that the input is very exact for the output. For example, `SetCore1` would result in a core affinity the same as Windows Task Manager would display. So that's only Core0. If the value would be bigger than the amount of cores, the `intptr` would be massively confused. Matching `listviewcheckboxes` to an external source which is only accessible in it's own language, is quite difficult. – BRO_THOM Jul 27 '15 at 15:21
  • @BRO_THOM You can always use wrapper classes to help you handle the mapping details. And don't worry too much about the `BitArray`s - they are pretty much designed for what you're doing, but it's not a big deal. You could even use simple `long`s for the whole affinity mask, it's not all that much more work than accessing an array (and you usually will not need to access the mask bit by bit). – Luaan Jul 28 '15 at 06:44
  • I've actually been bold enough to look througha couple of methods, and the one I found most useful is like such; the array `CheckState`'s value will be converted into Bytes using `Convert.ToByte` filling a `List` (creating 00001111 for example), which will be converted into a decimal in a `for` loop, causing false false false false true true true true to be converted into the decimal 15, which is what I needed. – BRO_THOM Jul 28 '15 at 08:34