Add recursive match

This commit is contained in:
Jcomp 2024-01-28 17:37:36 +00:00
parent 926b3c28a4
commit 798e1111ae

View file

@ -163,10 +163,9 @@ struct Action {
struct ActionHolder { struct ActionHolder {
Action[] actions; Action[] actions;
ulong[string] srcMap; ulong[string] srcMap;
void append(ActionType type, string src, string dst=null) { void append(ActionType type, string src, string dst=null) {
ulong pendingTarget = 0; ulong[] pendingTargets;
bool appendPending = false;
switch (type) { switch (type) {
case ActionType.changed: case ActionType.changed:
if (src in srcMap && actions[srcMap[src]].type == ActionType.changed) { if (src in srcMap && actions[srcMap[src]].type == ActionType.changed) {
@ -178,7 +177,7 @@ struct ActionHolder {
break; break;
case ActionType.deleted: case ActionType.deleted:
if (src in srcMap) { if (src in srcMap) {
pendingTarget = srcMap[src]; ulong pendingTarget = srcMap[src];
// Skip operations require reading local file that is gone // Skip operations require reading local file that is gone
switch (actions[pendingTarget].type) { switch (actions[pendingTarget].type) {
case ActionType.changed: case ActionType.changed:
@ -192,19 +191,34 @@ struct ActionHolder {
} }
break; break;
case ActionType.moved: case ActionType.moved:
if (src in srcMap) { for(int i = 0; i < actions.length; i++) {
pendingTarget = srcMap[src]; // Only match for latest operation
// Hold operations require reading local file that is moved after the target is moved online if (actions[i].src in srcMap) {
switch (actions[pendingTarget].type) { switch (actions[i].type) {
case ActionType.changed: case ActionType.changed:
case ActionType.createDir: case ActionType.createDir:
appendPending = true; // check if the source is the prefix of the target
actions[pendingTarget].skipped = true; string prefix = src ~ "/";
actions[pendingTarget].src = dst; string target = actions[i].src;
srcMap.remove(src); if (prefix[0] != '.')
break; prefix = "./" ~ prefix;
default: if (target[0] != '.')
break; target = "./" ~ target;
string comm = commonPrefix(prefix, target);
if (src == actions[i].src || comm.length == prefix.length) {
// Hold operations require reading local file that is moved after the target is moved online
pendingTargets ~= i;
actions[i].skipped = true;
srcMap.remove(actions[i].src);
if (comm.length == target.length)
actions[i].src = dst;
else
actions[i].src = dst ~ target[comm.length - 1 .. target.length];
}
break;
default:
break;
}
} }
} }
break; break;
@ -214,7 +228,7 @@ struct ActionHolder {
actions ~= Action(type, false, src, dst); actions ~= Action(type, false, src, dst);
srcMap[src] = actions.length - 1; srcMap[src] = actions.length - 1;
if (appendPending) { foreach (pendingTarget; pendingTargets) {
actions ~= actions[pendingTarget]; actions ~= actions[pendingTarget];
actions[$-1].skipped = false; actions[$-1].skipped = false;
srcMap[actions[$-1].src] = actions.length - 1; srcMap[actions[$-1].src] = actions.length - 1;