match
Synopsis
match volume header
match alternate volume header
match journal
match journal information block
match catalog file
match attributes file
match startup file
match extents file
match allocation file
match bad block file
match files where <match-expr>
Description
Defines the conditions under which a class will match a file. If more than one match specification is given for a class, a match of any one of the specifications will cause the class to match.
match may be followed either by the name of a volume data structure, or
alternatively by the phrase files where, followed by a match
expression. We recommend that you avoid the form with the volume data
structure names, as it is really intended for use in the built-in class set
definitions.
Match expressions are compiled into a form that iDefrag can interpret quickly to keep extent classification fast; most expressions compile and execute quickly, but a few impose a compile time or match-time penalty (there is a table later in this description that lists potentially problematic constructs).
Tip
Some match expressions have a performance penalty associated with them. Check out the Performance Tips section below for more information.
A match-expr or match expression is a Boolean expression consisting of comparisons of properties and values, logical operators and a few other predicates. Currently supported properties are
| Property | Description | Can compare with |
|---|---|---|
| name | The name of the file. | A string or regular expression |
| id | The catalog node ID of the file. | A number |
| size | The size of the file; this uses the size of the data fork, if present, or the resource fork otherwise. | A number |
| creator | The four character creator code for this file. | A number, string or regular expression |
| type | The four character type code for this file. | A number, string or regular expression |
| content modification date | The last time at which the file was modified. | A string or number of seconds since 1970 |
| attribute modification date | The last time at which the file’s attributes were modified. | A string or number of seconds since 1970 |
| access date | The last time at which the file was accessed. | A string or number of seconds since 1970 |
| creation date | The time at which the file was created. | A string or number of seconds since 1970 |
| backup date | The time at which the file was backed-up. | A string or number of seconds since 1970 |
| owner | The UID of the owner of the file. | A number |
| group | The GID of the group of the file. | A number |
| mode | The file’s UNIX mode. | A number |
| admin flags | The file’s administrative flags. | A number |
| owner flags | The file’s owner-specific flags. | A number |
| resource fork size | The total size of the file’s resource fork. | A number |
| data fork size | The total size of the file’s data fork. | A number |
| containing folder | The folder immediately containing the file (for sorting, this property refers to the catalog node ID of the containing folder, not the name). | A string, regular expression, or the catalog ID of the folder |
The operators are for the most part straightforward, with the possible
exception of the ~= and ~!= operators (the match operators), which
aside from their obvious use matching regular expressions against string
properties can be used to match bitmasks against numeric properties. For
instance, 0b1010 ~= 0b0010 is true, whilst 0b1010 ~= 0b0001 and
0b1010 ~!= 0b1000 are both false. (Note that having constants on both
sides of an expression is not actually supported by iDefrag; the example is
for illustrative purposes only.) A summary of the available operators is
given below, in order of precedence:
| Operator | Example | Description |
|---|---|---|
| (...) | (size > 1024 or owner = 501) and (creator != 0 or type != 0) | Used to disambiguate expressions by explicitly grouping terms |
| not | not (size > 1024 or owner = 501) | Inverts the given expression |
| = | size = 1024 | True if the property is equal to the value |
| name = “Foo” | ||
| != | size != 1024 | True if the property is not equal to the value |
| name != “Foo” | ||
| < | size < 1024 | True if the property is less than the value |
| name < “Foo” | ||
| > | size > 1024 | True if the property is greater then the value |
| name > “Foo” | ||
| <= | size <= 1024 | True if the property is less than or equal to the value |
| name <= “Foo” | ||
| >= | size >= 1024 | True if the property is greater than or equal to the value |
| name >= “Foo” | ||
| ~= | mode ~= 0022 | For numeric values, matches if the bits set in the value are also set in the property For string values, matches if the regular expression specified in the string matches the property |
| name ~= “Foo(bar)?” | ||
| ~!= | size ~!= 0022 | For numeric values, matches if the bits set in the value are not set in the property For string values, matches if the regular expression specified in the string does not match the property |
| name ~!= “Foo(bar)?” | ||
| and | size >= 1024 and name >= “Foo” | True if both expressions are true If the left hand side is false, the right hand side is never evaluated |
| or | size >= 1024 or name >= “Foo” | True if either expression is true If the left hand side is true, the right hand side is never evaluated |
iDefrag also supports four predicate expressions, namely:
| Expression | Meaning |
|---|---|
| file is within “folder” | True if the file is within the specified folder or any of its subfolders. Note the difference between |
| file isn’t within “folder” | True if the file is not within the specified folder or any of its subfolders. |
| file is fragmented | True if either the data or resource fork of the file is fragmented. |
| file isn’t fragmented | True if both the data and resource fork of the file are not fragmented. Note that the data fork may not be contiguous with the resource fork. |
Performance Tips
Certain type of match expression have a substantial effect on performance, either during compilation of the match engine, or at match time when iDefrag is attempting to match file extents with classes.
Tip
If you need to use an expensive expression, try to restrict it so that it will only be evaluated when absolutely necessary.
A good way to do this is to put the expensive expression in the right
hand side of an and or or expression, as those operators only
evaluate the right hand side if they are unable to determine the
result from the left hand side.
The table below lists the expressions that are potentially expensive.
| Expression | Penalty at | Why? |
|---|---|---|
| file is within “folder” | Compile | At compile time, iDefrag will search the folder and all subfolders to build a list of catalog IDs for all subfolders. This can be expensive for deep
hierarchies like |
| file isn’t within | ||
| containing folder ~= <regexp> | Match | Regular expression matching must be performed at match time. Also forces iDefrag to find the full path of the folder at match time (this is very expensive). |
| containing folder ~!= <regexp> | ||
| name ~= <regexp> | Match | Regular expression matching must be performed at match time. If regexp starts with a “/” character, it is assumed that it will match a full path, which forces iDefrag to find the full path of the file at match time (this is very expensive). |
| name ~!= <regexp> | ||
| containing folder >= <string> | Match | Forces iDefrag to find the full path of the folder at match time (this is very exprensive). This problem does not exist for the
|
| containing folder > <string> | ||
| containing folder <= <string> | ||
| containing folder < <string> | ||
| name >= <string> | Match | If string starts with a “/” character, it is assumed that it is a full path, which forces iDefrag to find the full path of the file at match time (this is very expensive). This problem does not exist for the
|
| name > <string> | ||
| name <= <string> | ||
| name < <string> |
Match time penalties are generally more problematic than compile-time penalties because matching processes very large numbers of files on a typical disk.
The most serious performance issue is if iDefrag is forced to look up the full
paths for large numbers of items at match time. It’s best to avoid full path
matching except with the = and != operators if at all possible, and if
you must use it in other circumstances then put it on the right hand side of
an and or or expression.
Additionally, iDefrag runs matching in class priority order, so it’s better to put expensive match statements in classes that have a lower priority, so that files that match other class sets are not subject to the performance penalty from evaluating an expensive match expression against them.
Example
class "BSD" {
match files where file is within "/usr" or file is within "/bin"
match files where file is within "/etc"
color "#ffe000"
}
class "Big" {
match files where size > 104857600
color "#ff00ff"
}