[fpc-pascal] Re: Sets as array index?

J├╝rgen Hestermann juergen.hestermann at gmx.de
Tue Oct 15 17:35:26 CEST 2013

Am 2013-10-15 11:00, schrieb leledumbo:
 > I := TagArray[ord(TagSet)];
 > I := TagArray[ord([tag1,tag5])];
 > It's unclear what you expect from such statements. I think you better
 > explain the high level problem, I smell a misdesign in the solution.

Yes, there is always the danger of overcomplicating things.
But I think in this case it makes sense.

I have a file manager that logs whole directory branches.
Files can have attributes like "Tagged" or "matching filter mask".
There can be even more attributes like multiple tag sets or whatever:

type FlagType     = (Tagged,FileMaskMatch);
      FlagSetType  = set of FlagTyp;

I now want to store the number of files and the bytes for each directory branch.
All possible set combination need to be considered because I may show all files that:

are tagged                         = [Tagged]
match a filter mask                = [FileMaskMatch]
are tagged AND match a filter mask = [Tagged,FileMaskMatch]
all files                          = []

This makes 4 possible combinations but for a 3rd attribute
I already have 8 and yet another doubles it to 16.

For each of these possible sets I want to store:

FileSumtype  = record
                Number : Cardinal;
                Bytes  : QWord;
                end; // of record


type BranchSumType = array[0..(1 shl (ord(High(FlagSetTyp))+1))-1] of FileSumType; // 0..2^n-1

I can now use a set variable

var FlagSet : FlagSetType;

to store what I want to display and use this variable for indexing the array

var BranchSum : BranchSumType;

when storing file information I can store them for all set combinations:

BranchSum[byte([                    ])].Number := ...;
BranchSum[byte([                    ])].Byte   := ...;
BranchSum[byte([       FileMaskMatch])].Number := ...;
BranchSum[byte([       FileMaskMatch])].Byte   := ...;
BranchSum[byte([Tagged              ])].Number := ...;
BranchSum[byte([Tagged              ])].Byte   := ...;
BranchSum[byte([Tagged,FileMaskMatch])].Number := ...;
BranchSum[byte([Tagged,FileMaskMatch])].Byte   := ...;

This is convenient as I need to use procedures to propagate these numbers up in the tree,
but not always all of them (because not all of them change when I only change the filter mask).

So I can use a FileSet variable as parameter for a procedure and index the array with it:

procedure PropagateUp(const F : FileSetType; const Values : FileSumType);
BranchSum[byte(F)] := Values[byte(F)];

So far this works fine and is quite fast.

More information about the fpc-pascal mailing list