Skip to content

Commit

Permalink
Add DisableGC option to document (#644)
Browse files Browse the repository at this point in the history
Recently we have implemented multi-user undo/redo feature and added
inverse operation for Text.edit. While implementing, we noticed that
the inverse operation accessed the removed node by GC. To address this
issue, we've added the disableGC option to skip GC temporarily.
  • Loading branch information
hackerwins authored Sep 15, 2023
1 parent 1594345 commit 2a49cfc
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/document/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ import {
PresenceChangeType,
} from '@yorkie-js-sdk/src/document/presence/presence';

/**
* `DocumentOptions` are the options to create a new document.
*
* @public
*/
export interface DocumentOptions {
/**
* `disableGC` disables garbage collection if true.
*/
disableGC?: boolean;
}

/**
* `DocumentStatus` represents the status of the document.
* @public
Expand Down Expand Up @@ -388,6 +400,7 @@ type PathOf<TDocument, Depth extends number = 10> = PathOfInternal<
export class Document<T, P extends Indexable = Indexable> {
private key: DocumentKey;
private status: DocumentStatus;
private opts: DocumentOptions;

private changeID: ChangeID;
private checkpoint: Checkpoint;
Expand All @@ -412,7 +425,9 @@ export class Document<T, P extends Indexable = Indexable> {
*/
private presences: Map<ActorID, P>;

constructor(key: string) {
constructor(key: string, opts?: DocumentOptions) {
this.opts = opts || {};

this.key = key;
this.status = DocumentStatus.Detached;
this.root = CRDTRoot.create();
Expand Down Expand Up @@ -888,6 +903,10 @@ export class Document<T, P extends Indexable = Indexable> {
* @internal
*/
public garbageCollect(ticket: TimeTicket): number {
if (this.opts.disableGC) {
return 0;
}

if (this.clone) {
this.clone.root.garbageCollect(ticket);
}
Expand Down
23 changes: 23 additions & 0 deletions test/integration/gc_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,29 @@ describe('Garbage Collection', function () {
assert.equal(0, doc.getGarbageLen());
});

it('disable GC test', function () {
const doc = new yorkie.Document<{
1: number;
2?: Array<number>;
3: number;
}>('test-doc', { disableGC: true });

doc.update((root) => {
root['1'] = 1;
root['2'] = [1, 2, 3];
root['3'] = 3;
}, 'set 1, 2, 3');
assert.equal('{"1":1,"2":[1,2,3],"3":3}', doc.toSortedJSON());

doc.update((root) => {
delete root['2'];
}, 'deletes 2');
assert.equal('{"1":1,"3":3}', doc.toSortedJSON());
assert.equal(4, doc.getGarbageLen());
assert.equal(0, doc.garbageCollect(MaxTimeTicket));
assert.equal(4, doc.getGarbageLen());
});

it('garbage collection test2', function () {
const size = 10000;
const doc = new yorkie.Document<{ 1?: Array<unknown> }>('test-doc');
Expand Down

0 comments on commit 2a49cfc

Please sign in to comment.