Lab
Object pool
type Job = { invoice: string; customer: string; landscape?: boolean };
// A browser tab. account is the customer it is signed in as, or null.
class Tab {
id: number;
account: string | null = null;
landscape = false;
constructor(id: number) {
this.id = id;
}
}
// The team's first step: it opens a tab for every job and closes it
// afterwards. Nothing is reused yet, and size is not used.
class TabPool {
constructor(size: number) {}
acquire(): Tab | null {
return openTab();
}
release(tab: Tab): void {
closeTab(tab);
}
}
// Signing in is slow, so the renderer signs in only when the tab is signed
// out. It relies on every tab it borrows being signed out.
function renderInvoice(tab: Tab, job: Job): string {
if (tab.account === null) tab.account = job.customer;
if (job.landscape !== undefined) tab.landscape = job.landscape;
const layout = tab.landscape ? 'landscape' : 'portrait';
return `${job.invoice} for ${job.customer}: tab ${tab.id} as ${tab.account}, ${layout}`;
}
// One job: borrow a tab, render, give the tab back on every path.
function printInvoice(pool: TabPool, job: Job): string {
const tab = pool.acquire();
if (!tab) return `${job.invoice}: no tab free`;
try {
return renderInvoice(tab, job);
} finally {
pool.release(tab);
}
}
// ---- Checker plumbing: you don't need to edit this. ----
// The browser host. Opening a tab is slow and memory is short, so it counts
// every tab opened and closed, and the most open at once. The checker
// resets it before each case.
const host = { opened: 0, open: 0, mostOpen: 0, closed: 0, wedged: [] as number[] };
function openTab(): Tab {
host.opened++;
host.open++;
host.mostOpen = Math.max(host.mostOpen, host.open);
return new Tab(host.opened);
}
function closeTab(tab: Tab): void {
host.open--;
host.closed++;
}
function resetHost(): void {
Object.assign(host, { opened: 0, open: 0, mostOpen: 0, closed: 0, wedged: [] });
}
function hostLine(): string {
return `opened ${host.opened}, most open ${host.mostOpen}, closed ${host.closed}`;
}