mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-01-14 08:37:56 +00:00
Docs: Update benchmark results
This commit is contained in:
@@ -1,59 +1,55 @@
|
||||
const findAvailableSlots = async (a, b, o) => {
|
||||
const { parseISO, formatISO, addDays, startOfDay } = await import('https://cdn.skypack.dev/date-fns@2.30.0');
|
||||
const dur = o.durationMinutes * 6e4;
|
||||
const rng = [parseISO(o.searchRange.start), parseISO(o.searchRange.end)];
|
||||
const split = t => t.split(':').map(Number);
|
||||
const hrs = { s: split(o.workHours.start), e: split(o.workHours.end) };
|
||||
const busy = [...a, ...b]
|
||||
.map(v => ({ start: parseISO(v.start), end: parseISO(v.end) }))
|
||||
.map(v => {
|
||||
const s = new Date(Math.max(v.start, rng[0]));
|
||||
const e = new Date(Math.min(v.end, rng[1]));
|
||||
return s < e ? { start: s, end: e } : null;
|
||||
})
|
||||
.filter(Boolean)
|
||||
.sort((x, y) => x.start - y.start)
|
||||
.reduce((m, v) => {
|
||||
const last = m[m.length - 1];
|
||||
if (!last || v.start > last.end) m.push({ start: new Date(v.start), end: new Date(v.end) });
|
||||
else if (v.end > last.end) last.end = new Date(v.end);
|
||||
return m;
|
||||
}, []);
|
||||
const slots = [];
|
||||
const collect = (s, e) => {
|
||||
let a = s.getTime(), b = e.getTime();
|
||||
while (a + dur <= b) {
|
||||
const r = a + dur;
|
||||
slots.push({ start: formatISO(new Date(a)), end: formatISO(new Date(r)) });
|
||||
a = r;
|
||||
}
|
||||
};
|
||||
let idx = 0;
|
||||
for (let d = startOfDay(rng[0]); d <= rng[1]; d = addDays(d, 1)) {
|
||||
const ws = new Date(d);
|
||||
ws.setHours(hrs.s[0], hrs.s[1], 0, 0);
|
||||
const we = new Date(d);
|
||||
we.setHours(hrs.e[0], hrs.e[1], 0, 0);
|
||||
const winStart = new Date(Math.max(ws, rng[0]));
|
||||
const winEnd = new Date(Math.min(we, rng[1]));
|
||||
if (winStart >= winEnd) continue;
|
||||
let cursor = winStart;
|
||||
while (idx < busy.length && busy[idx].end <= winStart) idx++;
|
||||
let view = idx;
|
||||
let done = false;
|
||||
while (view < busy.length && busy[view].start < winEnd) {
|
||||
const gapEnd = new Date(Math.min(busy[view].start, winEnd));
|
||||
if (gapEnd > cursor) collect(cursor, gapEnd);
|
||||
cursor = new Date(Math.max(cursor, busy[view].end));
|
||||
if (cursor >= winEnd) {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
view++;
|
||||
}
|
||||
if (!done && cursor < winEnd) collect(cursor, winEnd);
|
||||
idx = view;
|
||||
const luxon=import('https://cdn.skypack.dev/luxon');
|
||||
|
||||
const findAvailableSlots=async(c1,c2,k)=>{
|
||||
const {DateTime}=await luxon;
|
||||
const {durationMinutes:d,searchRange:r,workHours:w}=k;
|
||||
const zone=DateTime.fromISO(r.start).zoneName;
|
||||
const iso=v=>DateTime.fromISO(v,{zone});
|
||||
const rangeStart=iso(r.start);
|
||||
const rangeEnd=iso(r.end);
|
||||
if(rangeEnd<=rangeStart)return[];
|
||||
const [hs,ms]=w.start.split(':').map(Number);
|
||||
const [he,me]=w.end.split(':').map(Number);
|
||||
const daysEnd=rangeEnd.startOf('day');
|
||||
const windows=[];
|
||||
for(let day=rangeStart.startOf('day');day<=daysEnd;day=day.plus({days:1})){
|
||||
let s=day.set({hour:hs,minute:ms,second:0,millisecond:0});
|
||||
let e=day.set({hour:he,minute:me,second:0,millisecond:0});
|
||||
if(e<=s||e<=rangeStart||s>=rangeEnd)continue;
|
||||
if(s<rangeStart)s=rangeStart;
|
||||
if(e>rangeEnd)e=rangeEnd;
|
||||
windows.push({start:s,end:e});
|
||||
}
|
||||
return slots;
|
||||
if(!windows.length)return[];
|
||||
const busy=[...c1,...c2].map(v=>{
|
||||
let s=iso(v.start),e=iso(v.end);
|
||||
if(e<=s||e<=rangeStart||s>=rangeEnd)return null;
|
||||
if(s<rangeStart)s=rangeStart;
|
||||
if(e>rangeEnd)e=rangeEnd;
|
||||
return{start:s,end:e};
|
||||
}).filter(Boolean).sort((a,b)=>a.start.valueOf()-b.start.valueOf());
|
||||
const merged=[];
|
||||
for(const slot of busy){
|
||||
const last=merged[merged.length-1];
|
||||
if(last&&slot.start<=last.end){
|
||||
if(slot.end>last.end)last.end=slot.end;
|
||||
}else merged.push({start:slot.start,end:slot.end});
|
||||
}
|
||||
const out=[];
|
||||
const push=(s,e)=>e.diff(s,'minutes').minutes>=d&&out.push({start:s.toISO(),end:e.toISO()});
|
||||
for(const wSlot of windows){
|
||||
let cur=wSlot.start;
|
||||
for(const b of merged){
|
||||
if(b.start>=wSlot.end)break;
|
||||
if(b.end<=wSlot.start)continue;
|
||||
const bs=b.start>wSlot.start?b.start:wSlot.start;
|
||||
const be=b.end<wSlot.end?b.end:wSlot.end;
|
||||
if(bs>cur)push(cur,bs);
|
||||
if(be>cur)cur=be;
|
||||
if(cur>=wSlot.end)break;
|
||||
}
|
||||
if(cur<wSlot.end)push(cur,wSlot.end);
|
||||
}
|
||||
return out;
|
||||
};
|
||||
export default findAvailableSlots;
|
||||
Reference in New Issue
Block a user