-
-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
126 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
namespace $ { | ||
function stub_ids(max = 10): string[] { | ||
const ids: string[] = [] | ||
for (let i = 0; i < max; i++) { | ||
ids.push($mol_stub_code()) | ||
} | ||
return ids | ||
} | ||
|
||
function make_range() { | ||
const range = new $mol_range3<string>() | ||
const chunk_size = 10 | ||
const chunks = [ | ||
stub_ids(chunk_size), | ||
stub_ids(chunk_size), | ||
stub_ids(chunk_size / 2), | ||
] | ||
const count = chunks.reduce((acc, row) => acc + row.length, 0) | ||
range.count = () => count | ||
range.chunk_size = () => chunk_size | ||
range.chunk = offset => chunks[offset] | ||
|
||
return { range, chunks } | ||
} | ||
|
||
$mol_test({ | ||
|
||
'chunk addressing'() { | ||
const { range, chunks } = make_range() | ||
const arr = range.range() | ||
|
||
$mol_assert_equal(arr[0], chunks[0][0]) | ||
$mol_assert_equal(arr.at(-1), chunks.at(-1)?.at(-1)) | ||
} | ||
|
||
}) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
namespace $ { | ||
export class $mol_range3<Item> extends $mol_range2_array<Item> { | ||
count(): number { | ||
throw new Error('implement') | ||
} | ||
|
||
chunk(offset: number): readonly Item[] { | ||
throw new Error('implement') | ||
} | ||
|
||
chunk_size() { | ||
return 100 | ||
} | ||
|
||
page(page: number) { | ||
return this.chunk(page * this.chunk_size()) | ||
} | ||
|
||
item(index: number) { | ||
const limit = this.chunk_size() | ||
|
||
const chunk_index = index % limit | ||
const page = Math.floor(index / limit) | ||
|
||
const chunk = this.page(page) | ||
const id = chunk[chunk_index] | ||
|
||
return id | ||
} | ||
|
||
@ $mol_mem | ||
temp(next?: readonly Item[]) { | ||
return next ?? [] | ||
} | ||
|
||
push(...ids: readonly Item[]) { | ||
this.temp([ ...this.temp(), ...ids ]) | ||
this.temp_cut() | ||
|
||
return this.length | ||
} | ||
|
||
temp_chunk_min() { | ||
return 1 | ||
} | ||
|
||
temp_cut() { | ||
const temp = this.temp() | ||
if (! temp) return | ||
|
||
const limit = this.chunk_size() | ||
const delete_chunks = Math.ceil(temp.length / limit) - this.temp_chunk_min() | ||
if (delete_chunks <= 0) return | ||
|
||
const delete_count = delete_chunks * limit | ||
this.removed_count = this.removed_count + delete_count | ||
this.temp(temp.slice(delete_count)) | ||
} | ||
|
||
at(index: number) { | ||
const count = this.count() + this.removed_count | ||
if (index < 0) index = Math.max(0, count + this.temp().length + index) | ||
|
||
if (index < count) return this.item(index) | ||
return this.temp()[index - count] | ||
} | ||
|
||
protected removed_count = 0 | ||
|
||
get length() { | ||
return this.count() + this.removed_count + this.temp().length | ||
} | ||
|
||
@ $mol_mem | ||
range() { | ||
return $mol_range2(index => this.at(index), () => this.length, this) | ||
} | ||
|
||
} | ||
} |