Checks if the operands of the expression can be swapped to improve performance. @return result of check
()
| 47 | * @return result of check |
| 48 | */ |
| 49 | final boolean swap() { |
| 50 | final Expr expr1 = exprs[0], expr2 = exprs[1]; |
| 51 | |
| 52 | // keep dedicated function calls as left-hand operand |
| 53 | if(COUNT.is(expr1) || POSITION.is(expr1)) return false; |
| 54 | |
| 55 | // move position() and count() to the left: position() = 123 |
| 56 | boolean swap = COUNT.is(expr2) || POSITION.is(expr2); |
| 57 | // right operand is a value, and left operand yields more results: (1, 2) = 3 |
| 58 | if(!swap && expr2 instanceof Value) |
| 59 | return expr1 instanceof Value && expr1.size() > expr2.size(); |
| 60 | |
| 61 | // move static value to the right: $words = 'words' |
| 62 | if(!swap) swap = expr1 instanceof Value; |
| 63 | // move larger input to the right: $small = $large |
| 64 | if(!swap) swap = expr1.size() > 1 && expr1.size() > expr2.size(); |
| 65 | // move context item to the left: . = $input |
| 66 | if(!swap) swap = expr2 instanceof ContextValue && expr2.size() == 1 && |
| 67 | !(expr1 instanceof ContextValue); |
| 68 | // move path to the left: word/text() = $word |
| 69 | if(!swap) swap = !(expr1 instanceof final Path pth1 && pth1.root == null) && |
| 70 | expr2 instanceof final Path pth2 && pth2.root == null; |
| 71 | |
| 72 | return swap; |
| 73 | } |
| 74 | |
| 75 | /** |
| 76 | * If possible, returns an optimized expression with inverted operands. |