← Object pool lesson
Lab

Object pool

Sign in to run your code

Read the brief and the starter here. With a free account you can edit it, run the sample, step through it and check your work, and your progress is kept.

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}`;
}