SystemDrills

Session: Sign in to solve

Solution.txt

Transaction Query Pager

Problem

Design TransactionQueryPager to filter a fixed collection of transactions and return deterministic pages that a caller can continue with a cursor.

Requirements

  • User filter. If userId is present, return only transactions whose case-sensitive user ID is equal to it. If it is absent, do not filter by user.
  • Currency filter. If currency is present, return only transactions whose case-sensitive currency is equal to it. If it is absent, do not filter by currency.
  • Time filter. If startTime and endTime are present, include only timestamps in the inclusive range startTime <= timestamp <= endTime. If both are absent, do not filter by time.
  • Order. Sort matching transactions by timestamp ascending, then by unique id ascending when timestamps are equal.
  • Continuation. A null cursor starts before the first matching transaction. A non-null cursor starts strictly after the transaction key it represents, so that transaction and every earlier transaction are excluded.
  • Page size. Return at most pageSize consecutive matching transactions after the cursor boundary.
  • More pages. If matching transactions remain, return a non-null nextCursor that represents the timestamp and ID of the final returned transaction.
  • Last page. If no matching transaction remains after the page, return a null nextCursor. An empty result is therefore terminal.
  • Filter composition. Return a transaction only when it satisfies every supplied user, currency, and time filter.

API

SignatureReturnsBehavior
TransactionQueryPager(transactions: Transaction[])Not applicableCopies the fixed transaction collection. Transaction IDs are unique.
query(filter: TransactionFilter, pageSize: integer, cursor: string?)TransactionPageApplies all supplied filters, order, cursor boundary, and page limit without changing the stored transactions.

Transaction has id: string, timestamp: long, userId: string, currency: string, and amount: long.

TransactionFilter has optional userId: string?, currency: string?, startTime: long?, and endTime: long?. The two time fields are both present or both absent.

TransactionPage has transactions: Transaction[] and nextCursor: string?. A cursor is an opaque token returned by this pager for the same filter. It represents the final transaction's (timestamp, id) order key.

Examples

Construct the pager with transactions t2=(20,u1,USD,7), t1=(10,u1,USD,5), and t3=(20,u1,EUR,9), where each tuple lists (timestamp,userId,currency,amount).

StepOperationResult
1query({userId: "u1", currency: "USD", startTime: 10, endTime: 20}, 1, null)transactions=[t1]; nextCursor is non-null.
2query(the same filter, 1, step1.nextCursor)transactions=[t2]; nextCursor=null.

For equal timestamps, IDs break the tie. If transactions b and a both have timestamp 5, query({}, 10, null) returns [a,b] with a null cursor.

Constraints

  • The constructor receives from 0 to 100,000 transactions.
  • Each id, userId, and currency contains 1 to 64 case-sensitive ASCII letters, digits, dots, colons, underscores, or hyphens.
  • Each timestamp and amount fits in a signed 64-bit integer.
  • A supplied time range has startTime <= endTime.
  • pageSize is from 1 to 1,000.
  • A non-null cursor came from an earlier call on this pager with the same filter.

Notes

Calls are sequential. The constructor collection does not change after the pager is created.

PRIVATE WORKSPACE

Checking your session…

The statement is public. The editor, editorial, submissions, and saved work are private.