Skip to content

Commit c2b372c

Browse files
committed
refactor: rename select→getByRank, rank→getRank
Consistent naming: getRank/getByRank/rangeByRank — all centered on 'Rank'. - select() → getByRank(): element at k-th position in tree order - rank() → getRank(): number of elements preceding key in tree order - _selectIterative/_selectRecursive → _getByRankIterative/_getByRankRecursive - _rankIterative/_rankRecursive → _getRankIterative/_getRankRecursive - All JSDoc, tests, README, guides, RFC updated
1 parent a662183 commit c2b372c

14 files changed

Lines changed: 209 additions & 209 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,11 @@ const tree = new RedBlackTree<number, string>([
289289
], { comparator: (a, b) => b - a, enableOrderStatistic: true });
290290

291291
// select(k) — find k-th element, O(log n)
292-
tree.select(0); // 100 (1st in tree order)
293-
tree.select(2); // 92 (3rd in tree order)
292+
tree.getByRank(0); // 100 (1st in tree order)
293+
tree.getByRank(2); // 92 (3rd in tree order)
294294

295295
// rank(key) — count elements preceding key in tree order, O(log n)
296-
tree.rank(92); // 2 (2 elements before 92 in tree order)
296+
tree.getRank(92); // 2 (2 elements before 92 in tree order)
297297

298298
// rangeByRank — pagination, O(log n + k)
299299
tree.rangeByRank(0, 2); // [100, 95, 92] — top 3

docs-site-docusaurus/docs/guide/concepts.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,12 @@ scores.sort((a, b) => a - b);
342342
const median = scores[Math.floor(scores.length / 2)]; // re-sort on every update
343343
```
344344

345-
✅ Order-statistic tree: O(log n) select/rank with live updates:
345+
✅ Order-statistic tree: O(log n) getByRank/getRank with live updates:
346346

347347
```javascript
348348
const tree = new RedBlackTree(scores, { enableOrderStatistic: true });
349-
const median = tree.select(Math.floor(tree.size / 2)); // O(log n)
350-
const rank = tree.rank(92); // "how many scores below 92?" — O(log n)
349+
const median = tree.getByRank(Math.floor(tree.size / 2)); // O(log n)
350+
const rank = tree.getRank(92); // "how many scores below 92?" — O(log n)
351351
const top3 = tree.rangeByRank(tree.size - 3, tree.size - 1); // O(log n + 3)
352352
```
353353

docs-site-docusaurus/docs/guide/guides.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ interface Player {
230230
}
231231

232232
class Leaderboard {
233-
// enableOrderStatistic gives O(log n) select/rank/rangeByRank
233+
// enableOrderStatistic gives O(log n) getByRank/getRank/rangeByRank
234234
private scores = new RedBlackTree<number, Player>(
235235
[],
236236
{ comparator: (a, b) => b - a, enableOrderStatistic: true }
@@ -255,19 +255,19 @@ class Leaderboard {
255255
// O(log n) — direct rank lookup
256256
getRank(playerId: string): number {
257257
if (!this.players.has(playerId)) return -1;
258-
return this.scores.rank(this.players.get(playerId)!) + 1; // 1-based
258+
return this.scores.getRank(this.players.get(playerId)!) + 1; // 1-based
259259
}
260260

261261
// O(log n + k) — get k-th player by rank
262262
getPlayerAt(rank: number): Player | undefined {
263-
const key = this.scores.select(rank - 1); // 0-indexed internally
263+
const key = this.scores.getByRank(rank - 1); // 0-indexed internally
264264
return key !== undefined ? this.scores.get(key) : undefined;
265265
}
266266

267267
// O(log n + k) — players around a given player
268268
getAroundMe(playerId: string, range: number): Player[] {
269269
if (!this.players.has(playerId)) return [];
270-
const myRank = this.scores.rank(this.players.get(playerId)!);
270+
const myRank = this.scores.getRank(this.players.get(playerId)!);
271271
const start = Math.max(0, myRank - range);
272272
const end = Math.min(this.scores.size - 1, myRank + range);
273273
return this.scores.rangeByRank(start, end)

docs-site-docusaurus/docs/guide/overview.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ rbTree.print()
149149

150150
// Order-Statistic mode — O(log n) rank queries
151151
const ost = new RedBlackTree<number, string>([[1, 'A'], [2, 'B'], [3, 'C']], { enableOrderStatistic: true });
152-
ost.select(0); // 1 (smallest key)
153-
ost.rank(2); // 1 (one element before key 2)
152+
ost.getByRank(0); // 1 (smallest key)
153+
ost.getRank(2); // 1 (one element before key 2)
154154
ost.rangeByRank(0, 1); // [1, 2] (first two elements)
155155
```
156156

docs-site-docusaurus/docs/guide/quick-start.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,18 +47,18 @@ const tree = new RedBlackTree<number, string>([
4747
], { comparator: (a, b) => b - a, enableOrderStatistic: true });
4848

4949
// select(k) — find k-th element (0-indexed)
50-
console.log(tree.select(0)); // 100 (1st in tree order)
51-
console.log(tree.select(2)); // 92 (3rd in tree order)
50+
console.log(tree.getByRank(0)); // 100 (1st in tree order)
51+
console.log(tree.getByRank(2)); // 92 (3rd in tree order)
5252

5353
// rank(key) — how many elements before this key?
54-
console.log(tree.rank(92)); // 2 (2 elements before 92 in tree order)
54+
console.log(tree.getRank(92)); // 2 (2 elements before 92 in tree order)
5555

5656
// rangeByRank(start, end) — pagination
5757
console.log(tree.rangeByRank(0, 2)); // [100, 95, 92] — top 3
5858

59-
// Inverse property: select(rank(key)) === key
60-
const k = tree.rank(85);
61-
console.log(tree.select(k)); // 85
59+
// Inverse property: getByRank(getRank(key)) === key
60+
const k = tree.getRank(85);
61+
console.log(tree.getByRank(k)); // 85
6262
```
6363

6464
## Task Queue (Scheduling)

docs/GUIDES.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ interface Player {
225225
}
226226

227227
class Leaderboard {
228-
// enableOrderStatistic gives O(log n) select/rank/rangeByRank
228+
// enableOrderStatistic gives O(log n) getByRank/getRank/rangeByRank
229229
private scores = new RedBlackTree<number, Player>(
230230
[],
231231
{ comparator: (a, b) => b - a, enableOrderStatistic: true }
@@ -250,19 +250,19 @@ class Leaderboard {
250250
// O(log n) — direct rank lookup
251251
getRank(playerId: string): number {
252252
if (!this.players.has(playerId)) return -1;
253-
return this.scores.rank(this.players.get(playerId)!) + 1; // 1-based
253+
return this.scores.getRank(this.players.get(playerId)!) + 1; // 1-based
254254
}
255255

256256
// O(log n) — get k-th player by rank
257257
getPlayerAt(rank: number): Player | undefined {
258-
const key = this.scores.select(rank - 1); // 0-indexed internally
258+
const key = this.scores.getByRank(rank - 1); // 0-indexed internally
259259
return key !== undefined ? this.scores.get(key) : undefined;
260260
}
261261

262262
// O(log n + k) — players around a given player
263263
getAroundMe(playerId: string, range: number): Player[] {
264264
if (!this.players.has(playerId)) return [];
265-
const myRank = this.scores.rank(this.players.get(playerId)!);
265+
const myRank = this.scores.getRank(this.players.get(playerId)!);
266266
const start = Math.max(0, myRank - range);
267267
const end = Math.min(this.scores.size - 1, myRank + range);
268268
return this.scores.rangeByRank(start, end)

docs/rfcs/order-statistic-tree.md

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ enableOrderStatistic?: boolean; // default: false
3636

3737
When `false` (default):
3838
- `_count` is NOT maintained (no overhead)
39-
- `select()`, `rank()`, `rangeByRank()` throw `Error('Order statistic is not enabled')`
39+
- `getByRank()`, `getRank()`, `rangeByRank()` throw `Error('Order statistic is not enabled')`
4040

4141
When `true`:
4242
- `_count` is maintained on every insert, delete, and rotation
@@ -47,7 +47,7 @@ When `true`:
4747
The option propagates through the inheritance chain:
4848
```ts
4949
const map = new TreeMap<string, number>([], { enableOrderStatistic: true });
50-
map.select(0); // ✅ works
50+
map.getByRank(0); // ✅ works
5151
```
5252

5353
## API Design
@@ -93,29 +93,29 @@ const tree = new RedBlackTree<number>(
9393
{ enableOrderStatistic: true }
9494
);
9595

96-
tree.select(0); // 20 (smallest)
97-
tree.select(3); // 50 (median)
98-
tree.select(6); // 80 (largest)
99-
tree.select(7); // undefined (out of bounds)
100-
tree.select(-1); // undefined
96+
tree.getByRank(0); // 20 (smallest)
97+
tree.getByRank(3); // 50 (median)
98+
tree.getByRank(6); // 80 (largest)
99+
tree.getByRank(7); // undefined (out of bounds)
100+
tree.getByRank(-1); // undefined
101101

102102
// With callback — get node
103-
tree.select(3, node => node); // BSTNode { key: 50 }
103+
tree.getByRank(3, node => node); // BSTNode { key: 50 }
104104

105105
// With callback — get entry
106-
tree.select(3, node => [node.key, node.value]); // [50, undefined]
106+
tree.getByRank(3, node => [node.key, node.value]); // [50, undefined]
107107

108108
// TreeMap
109109
const map = new TreeMap<string, number>(
110110
[['alice', 95], ['bob', 87], ['charlie', 92]],
111111
{ enableOrderStatistic: true }
112112
);
113-
map.select(0); // 'alice' (keys sorted alphabetically)
114-
map.select(2); // 'charlie'
113+
map.getByRank(0); // 'alice' (keys sorted alphabetically)
114+
map.getByRank(2); // 'charlie'
115115

116116
// TreeSet
117117
const set = new TreeSet<number>([10, 20, 30], { enableOrderStatistic: true });
118-
set.select(1); // 20
118+
set.getByRank(1); // 20
119119
```
120120

121121
### rank(key) — Get the rank of a key
@@ -172,23 +172,23 @@ const tree = new RedBlackTree<number>(
172172
{ enableOrderStatistic: true }
173173
);
174174

175-
tree.rank(10); // 0 (smallest, 0 elements less than it)
176-
tree.rank(30); // 2 (20 and 10 are less)
177-
tree.rank(50); // 4
178-
tree.rank(25); // 2 (would be inserted at position 2)
179-
tree.rank(5); // 0 (would be inserted at position 0)
180-
tree.rank(100); // 5 (would be inserted at end)
175+
tree.getRank(10); // 0 (smallest, 0 elements less than it)
176+
tree.getRank(30); // 2 (20 and 10 are less)
177+
tree.getRank(50); // 4
178+
tree.getRank(25); // 2 (would be inserted at position 2)
179+
tree.getRank(5); // 0 (would be inserted at position 0)
180+
tree.getRank(100); // 5 (would be inserted at end)
181181

182182
// Inverse relationship
183-
tree.select(tree.rank(30)); // 30
184-
tree.rank(tree.select(2)!); // 2
183+
tree.getByRank(tree.getRank(30)); // 30
184+
tree.getRank(tree.getByRank(2)!); // 2
185185

186186
// TreeMap
187187
const map = new TreeMap<string, number>(
188188
[['alice', 95], ['bob', 87], ['charlie', 92]],
189189
{ enableOrderStatistic: true }
190190
);
191-
map.rank('bob'); // 1
191+
map.getRank('bob'); // 1
192192
```
193193

194194
### rangeByRank(start, end) — Get elements by rank range
@@ -312,8 +312,8 @@ rangeByRank(start: number, end: number): (K | undefined)[] {
312312
```
313313

314314
Each call site provides a sensible fallback value after `raise()`:
315-
- `select``undefined`
316-
- `rank``-1`
315+
- `getByRank``undefined`
316+
- `getRank``-1`
317317
- `rangeByRank``[]`
318318

319319
In `throw` mode (default), the fallback is never reached. In other modes, the function degrades gracefully.
@@ -324,12 +324,12 @@ New code uses `raise()`. Existing `throw` statements are gradually migrated —
324324

325325
## IterationType Support
326326

327-
Both `select` and `rank` walk a single root-to-leaf path, similar to `ceiling`/`floor`.
327+
Both `getByRank` and `getRank` walk a single root-to-leaf path, similar to `ceiling`/`floor`.
328328

329329
- **ITERATIVE** (default): while loop, O(1) space
330330
- **RECURSIVE**: function calls, O(log n) stack space
331331

332-
`rangeByRank` uses `select` + in-order traversal, both support IterationType.
332+
`rangeByRank` uses `getByRank` + in-order traversal, both support IterationType.
333333

334334
## Edge Cases
335335

@@ -374,7 +374,7 @@ In TreeMultiMap, a single node can represent multiple entries.
374374
- With callback
375375

376376
4. **Inverse relationship**
377-
- `select(rank(key)) === key` for all keys
377+
- `getByRank(getRank(key)) === key` for all keys
378378
- `rank(select(k)) === k` for all valid k
379379

380380
5. **Count maintenance**
@@ -390,14 +390,14 @@ In TreeMultiMap, a single node can represent multiple entries.
390390
- TreeMultiSet: duplicate handling
391391

392392
7. **enableOrderStatistic: false**
393-
- select/rank/rangeByRank all throw
393+
- getByRank/getRank/rangeByRank all throw
394394
- No count maintenance overhead (count stays 1)
395395

396396
8. **IterationType**
397397
- All methods produce same results with RECURSIVE and ITERATIVE
398398

399399
9. **Stress test**
400-
- Insert 10K random elements, verify select/rank consistency
400+
- Insert 10K random elements, verify getByRank/getRank consistency
401401
- Random insert/delete sequence, verify count integrity after each operation
402402

403403
## Implementation Order
@@ -408,8 +408,8 @@ In TreeMultiMap, a single node can represent multiple entries.
408408
4. Wire count updates into BST insert/delete
409409
5. Wire count updates into AVL rotations
410410
6. Wire count updates into RBT rotations + fixup
411-
7. Implement `select`
412-
8. Implement `rank`
411+
7. Implement `getByRank`
412+
8. Implement `getRank`
413413
9. Implement `rangeByRank`
414414
10. Verify all tests pass
415415
11. Run performance benchmark (before/after with enableOrderStatistic: false)

0 commit comments

Comments
 (0)