Document Search Engine
Tokenization, positional indexes, and stale updates
Ownership and transitions
A positional index maps tokens to document occurrence positions; phrase search intersects positions with offsets. Updating a document must remove its old postings before publishing new content, or stale terms and phrase positions survive. Ranking sorts score descending then ID. Tokenization and full reindexing cost O(document length); index lookup narrows candidates but phrase intersection and ranking still cost work.
Java boundaries
Use the supplied nested records as immutable value carriers. A record is only shallowly immutable: copy every retained mutable input and every outward list/map, including lists inside records. Absence is null; validation failures use IllegalArgumentException, missing-key purchase errors use NoSuchElementException, and invalid transaction boundaries use IllegalStateException. Java primitive types already exclude booleans from numeric inputs. Numeric values use long where signatures say long and all computations must fit signed 64-bit values. Calls in these service exercises are serialized.
Phrase matching depends on token positions and counts overlapping starts. Removing a document therefore requires removing both term membership and positional data:
import java.util.*;
class Example {
public static void main(String[] args) {
List<String> tokens = List.of("a", "a", "a");
List<String> phrase = List.of("a", "a");
assert tokens.subList(0, 2).equals(phrase);
assert tokens.subList(1, 3).equals(phrase);
assert !List.of("ab").contains("a");
}
}There are two matching starts, while a whole token ab is distinct from a. A set-only inverted index can identify candidate documents but cannot recover these phrase counts by itself.
Design boundary
Updates must replace all old postings and token counts as one public transition. The exercise fixes ASCII tokenization and exact deterministic ranking; stemming, linguistic segmentation, relevance scoring, persistence, and concurrent publication would need their own contracts.
Put it into practice
Implement the exercise in a full-screen workspace, then run its tests.