!7 cmodule RegexpMatcher > DynPrintLogAndEnabled { switchable bool verbose; transient L jobs = syncLinkedList(); transient ReliableSingleThread rst = dm_rst_inInit(this, r step); // stats transient long jobsDone; transient Job shortestRegexp, longestRegexp; transient Job quickestJob, slowestJob; sclass Job { S regexp, input; bool ignoreCase; O whenDone; // voidfunc(Matcher, bool). called with null if error S moduleID; // for who are we doing this long executionTime; // after it ran void clean { whenDone = null; } } void step { Job job; while (licensed() && (job = syncPopFirst(jobs)) != null) pcall { doJob(job); job.clean(); // update stats & print ++jobsDone; if (verbose) print("Regexp matching done in " + job.executionTime + " ms"); shortestRegexp = switchIfShorterInField regexp(job, shortestRegexp, r { if (verbose) print("New shortest regexp!") }); longestRegexp = switchIfLongerInField regexp(job, longestRegexp, r { if (verbose) print("New longest regexp!") }); if (quickestJob == null || job.executionTime < quickestJob.executionTime) { quickestJob = job; if (verbose) print("New quickest job!"); } if (slowestJob == null || job.executionTime > slowestJob.executionTime) { slowestJob = job; if (verbose) print("New slowest job!"); } } } void doJob(Job j) { if (!dm_moduleExists(j.moduleID)) ret; long time = sysNow(); Matcher m = null; bool found = false; pcall { m = safeRegexpPossiblyIC(j.ignoreCase, j.regexp, j.input); found = m.find(); } j.executionTime = elapsedMS(time); callF(j.whenDone, m, found); } // API void addJob(S moduleID, S regexp, S input, bool ignoreCase, O whenDone) q { jobs.add(nu Job(+moduleID, +regexp, +input, +ignoreCase, +whenDone)); // change(); rst.trigger(); } void deleteJobsForModule(S moduleID) q { syncFilterLinkedListInPlace(jobs, job -> eq(job.moduleID, moduleID)); // change(); } }