@peerbit/log 4.0.10 → 4.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/benchmark/memory/index.js +0 -1
- package/dist/benchmark/memory/index.js.map +1 -1
- package/dist/benchmark/memory/insert.js +0 -2
- package/dist/benchmark/memory/insert.js.map +1 -1
- package/dist/src/entry-index.d.ts +3 -3
- package/dist/src/entry-index.d.ts.map +1 -1
- package/dist/src/entry-index.js +22 -19
- package/dist/src/entry-index.js.map +1 -1
- package/dist/src/log.d.ts +42 -2
- package/dist/src/log.d.ts.map +1 -1
- package/dist/src/log.js +73 -60
- package/dist/src/log.js.map +1 -1
- package/dist/src/trim.d.ts.map +1 -1
- package/dist/src/trim.js +1 -2
- package/dist/src/trim.js.map +1 -1
- package/package.json +8 -8
- package/src/entry-index.ts +31 -33
- package/src/log.ts +100 -63
- package/src/trim.ts +1 -4
package/src/log.ts
CHANGED
|
@@ -274,7 +274,7 @@ export class Log<T> {
|
|
|
274
274
|
*/
|
|
275
275
|
async toArray(): Promise<Entry<T>[]> {
|
|
276
276
|
// we call init, because the values might be unitialized
|
|
277
|
-
return this.entryIndex.
|
|
277
|
+
return this.entryIndex.iterate([], this.sortFn.sort, true).all();
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
/**
|
|
@@ -456,7 +456,7 @@ export class Log<T> {
|
|
|
456
456
|
}
|
|
457
457
|
}
|
|
458
458
|
|
|
459
|
-
await this.load({ reload: false });
|
|
459
|
+
/* await this.load({ reload: false }); */
|
|
460
460
|
|
|
461
461
|
const nexts: Sorting.SortableEntry[] =
|
|
462
462
|
options.meta?.next ||
|
|
@@ -554,10 +554,12 @@ export class Log<T> {
|
|
|
554
554
|
}
|
|
555
555
|
|
|
556
556
|
async remove(
|
|
557
|
-
entry:
|
|
557
|
+
entry:
|
|
558
|
+
| { hash: string; meta: { next: string[] } }
|
|
559
|
+
| { hash: string; meta: { next: string[] } }[],
|
|
558
560
|
options?: { recursively?: boolean },
|
|
559
561
|
): Promise<Change<T>> {
|
|
560
|
-
await this.load({ reload: false });
|
|
562
|
+
/* await this.load({ reload: false }); */
|
|
561
563
|
const entries = Array.isArray(entry) ? entry : [entry];
|
|
562
564
|
|
|
563
565
|
if (entries.length === 0) {
|
|
@@ -567,46 +569,34 @@ export class Log<T> {
|
|
|
567
569
|
};
|
|
568
570
|
}
|
|
569
571
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
};
|
|
574
|
-
|
|
575
|
-
await this._onChange?.(change);
|
|
572
|
+
let removed: {
|
|
573
|
+
entry: ShallowOrFullEntry<T>;
|
|
574
|
+
fn: () => Promise<ShallowEntry | undefined>;
|
|
575
|
+
}[];
|
|
576
576
|
|
|
577
577
|
if (options?.recursively) {
|
|
578
|
-
await this.
|
|
578
|
+
removed = await this.prepareDeleteRecursively(entry);
|
|
579
579
|
} else {
|
|
580
|
+
removed = [];
|
|
580
581
|
for (const entry of entries) {
|
|
581
|
-
await this.
|
|
582
|
+
const deleteFn = await this.prepareDelete(entry.hash);
|
|
583
|
+
deleteFn.entry &&
|
|
584
|
+
removed.push({ entry: deleteFn.entry, fn: deleteFn.fn });
|
|
582
585
|
}
|
|
583
586
|
}
|
|
584
587
|
|
|
585
|
-
|
|
586
|
-
|
|
588
|
+
const change: Change<T> = {
|
|
589
|
+
added: [],
|
|
590
|
+
removed: removed.map((x) => x.entry),
|
|
591
|
+
};
|
|
587
592
|
|
|
588
|
-
|
|
589
|
-
from?: "tail" | "head";
|
|
590
|
-
amount?: number;
|
|
591
|
-
}): IterableIterator<string> {
|
|
592
|
-
const from = options?.from || "tail";
|
|
593
|
-
const amount = typeof options?.amount === "number" ? options?.amount : -1;
|
|
594
|
-
let next = from === "tail" ? this._values.tail : this._values.head;
|
|
595
|
-
const nextFn = from === "tail" ? (e: any) => e.prev : (e: any) => e.next;
|
|
596
|
-
return (function* () {
|
|
597
|
-
let counter = 0;
|
|
598
|
-
while (next) {
|
|
599
|
-
if (amount >= 0 && counter >= amount) {
|
|
600
|
-
return;
|
|
601
|
-
}
|
|
593
|
+
await this._onChange?.(change);
|
|
602
594
|
|
|
603
|
-
|
|
604
|
-
|
|
595
|
+
// invoke deletions
|
|
596
|
+
await Promise.all(removed.map((x) => x.fn()));
|
|
605
597
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
})();
|
|
609
|
-
} */
|
|
598
|
+
return change;
|
|
599
|
+
}
|
|
610
600
|
|
|
611
601
|
async trim(option: TrimOptions | undefined = this._trim.options) {
|
|
612
602
|
return this._trim.trim(option);
|
|
@@ -699,18 +689,25 @@ export class Log<T> {
|
|
|
699
689
|
heads.set(next, false);
|
|
700
690
|
}
|
|
701
691
|
}
|
|
692
|
+
|
|
702
693
|
for (const entry of entries) {
|
|
703
694
|
let isHead = heads.get(entry.hash)!;
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
695
|
+
let prev = this._joining.get(entry.hash);
|
|
696
|
+
if (prev) {
|
|
697
|
+
await prev;
|
|
698
|
+
} else {
|
|
699
|
+
const p = this.joinRecursively(entry, {
|
|
700
|
+
references,
|
|
701
|
+
isHead,
|
|
702
|
+
...options,
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
this._joining.set(entry.hash, p);
|
|
706
|
+
p.finally(() => {
|
|
707
|
+
this._joining.delete(entry.hash);
|
|
708
|
+
});
|
|
709
|
+
await p;
|
|
710
|
+
}
|
|
714
711
|
}
|
|
715
712
|
}
|
|
716
713
|
|
|
@@ -774,7 +771,10 @@ export class Log<T> {
|
|
|
774
771
|
|
|
775
772
|
if (entry.meta.type !== EntryType.CUT) {
|
|
776
773
|
for (const a of entry.meta.next) {
|
|
777
|
-
|
|
774
|
+
const prev = this._joining.get(a);
|
|
775
|
+
if (prev) {
|
|
776
|
+
await prev;
|
|
777
|
+
} else if (!(await this.has(a))) {
|
|
778
778
|
const nested =
|
|
779
779
|
options.references?.get(a) ||
|
|
780
780
|
(await Entry.fromMultihash<T>(this._storage, a, {
|
|
@@ -839,29 +839,47 @@ export class Log<T> {
|
|
|
839
839
|
return [];
|
|
840
840
|
}
|
|
841
841
|
|
|
842
|
-
/// TODO simplify methods below
|
|
843
842
|
async deleteRecursively(
|
|
844
|
-
from:
|
|
843
|
+
from:
|
|
844
|
+
| { hash: string; meta: { next: string[] } }
|
|
845
|
+
| { hash: string; meta: { next: string[] } }[],
|
|
846
|
+
skipFirst = false,
|
|
847
|
+
) {
|
|
848
|
+
const toDelete = await this.prepareDeleteRecursively(from, skipFirst);
|
|
849
|
+
const promises = toDelete.map(async (x) => {
|
|
850
|
+
const removed = await x.fn();
|
|
851
|
+
if (removed) {
|
|
852
|
+
return removed;
|
|
853
|
+
}
|
|
854
|
+
return undefined;
|
|
855
|
+
});
|
|
856
|
+
|
|
857
|
+
const results = Promise.all(promises);
|
|
858
|
+
return (await results).filter((x) => x) as ShallowEntry[];
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/// TODO simplify methods below
|
|
862
|
+
async prepareDeleteRecursively(
|
|
863
|
+
from:
|
|
864
|
+
| { hash: string; meta: { next: string[] } }
|
|
865
|
+
| { hash: string; meta: { next: string[] } }[],
|
|
845
866
|
skipFirst = false,
|
|
846
867
|
) {
|
|
847
868
|
const stack = Array.isArray(from) ? [...from] : [from];
|
|
848
869
|
const promises: (Promise<void> | void)[] = [];
|
|
849
870
|
let counter = 0;
|
|
850
|
-
const
|
|
871
|
+
const toDelete: {
|
|
872
|
+
entry: ShallowOrFullEntry<T>;
|
|
873
|
+
fn: () => Promise<ShallowEntry | undefined>;
|
|
874
|
+
}[] = [];
|
|
851
875
|
|
|
852
876
|
while (stack.length > 0) {
|
|
853
877
|
const entry = stack.pop()!;
|
|
854
878
|
const skip = counter === 0 && skipFirst;
|
|
855
879
|
if (!skip) {
|
|
856
|
-
const
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
const deletedEntry = await this.delete(entry.hash);
|
|
860
|
-
if (deletedEntry) {
|
|
861
|
-
/* this._nextsIndex.delete(entry.hash); */
|
|
862
|
-
deleted.push(deletedEntry);
|
|
863
|
-
}
|
|
864
|
-
}
|
|
880
|
+
const deleteFn = await this.prepareDelete(entry.hash);
|
|
881
|
+
deleteFn.entry &&
|
|
882
|
+
toDelete.push({ entry: deleteFn.entry, fn: deleteFn.fn });
|
|
865
883
|
}
|
|
866
884
|
|
|
867
885
|
for (const next of entry.meta.next) {
|
|
@@ -871,7 +889,7 @@ export class Log<T> {
|
|
|
871
889
|
// if there are no entries which is not of "CUT" type, we can safely delete the next entry
|
|
872
890
|
// figureately speaking, these means where are cutting all branches to a stem, so we can delete the stem as well
|
|
873
891
|
let hasAlternativeNext = !!entriesThatHasNext.find(
|
|
874
|
-
(x) => x.meta.type !== EntryType.CUT,
|
|
892
|
+
(x) => x.meta.type !== EntryType.CUT && x.hash !== entry.hash, // second arg is to avoid references to the same entry that is to be deleted (i.e we are looking for other entries)
|
|
875
893
|
);
|
|
876
894
|
if (!hasAlternativeNext) {
|
|
877
895
|
const ne = await this.get(next);
|
|
@@ -883,13 +901,32 @@ export class Log<T> {
|
|
|
883
901
|
counter++;
|
|
884
902
|
}
|
|
885
903
|
await Promise.all(promises);
|
|
886
|
-
return
|
|
904
|
+
return toDelete;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
async prepareDelete(
|
|
908
|
+
hash: string,
|
|
909
|
+
): Promise<
|
|
910
|
+
| { entry: ShallowEntry; fn: () => Promise<ShallowEntry | undefined> }
|
|
911
|
+
| { entry: undefined }
|
|
912
|
+
> {
|
|
913
|
+
let entry = await this._entryIndex.getShallow(hash);
|
|
914
|
+
if (!entry) {
|
|
915
|
+
return { entry: undefined };
|
|
916
|
+
}
|
|
917
|
+
return {
|
|
918
|
+
entry: entry.value,
|
|
919
|
+
fn: async () => {
|
|
920
|
+
await this._trim.deleteFromCache(hash);
|
|
921
|
+
const removedEntry = await this._entryIndex.delete(hash, entry.value);
|
|
922
|
+
return removedEntry;
|
|
923
|
+
},
|
|
924
|
+
};
|
|
887
925
|
}
|
|
888
926
|
|
|
889
927
|
async delete(hash: string): Promise<ShallowEntry | undefined> {
|
|
890
|
-
await this.
|
|
891
|
-
|
|
892
|
-
return removedEntry;
|
|
928
|
+
const deleteFn = await this.prepareDelete(hash);
|
|
929
|
+
return deleteFn.entry && deleteFn.fn();
|
|
893
930
|
}
|
|
894
931
|
|
|
895
932
|
/**
|
|
@@ -1003,7 +1040,7 @@ export class Log<T> {
|
|
|
1003
1040
|
|
|
1004
1041
|
const heads = providedCustomHeads
|
|
1005
1042
|
? (opts["heads"] as Array<Entry<T>>)
|
|
1006
|
-
: await this.
|
|
1043
|
+
: await this.entryIndex
|
|
1007
1044
|
.getHeads(undefined, {
|
|
1008
1045
|
type: "full",
|
|
1009
1046
|
signal: this._closeController.signal,
|
package/src/trim.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Cache } from "@peerbit/cache";
|
|
2
|
-
import { SumRequest } from "@peerbit/indexer-interface";
|
|
3
2
|
import PQueue from "p-queue";
|
|
4
3
|
import type { EntryIndex } from "./entry-index.js";
|
|
5
4
|
import type { ShallowEntry } from "./entry-shallow.js";
|
|
@@ -141,9 +140,7 @@ export class Trim<T> {
|
|
|
141
140
|
// TODO calculate the sum and cache it and update it only when entries are added or removed
|
|
142
141
|
const byteLengthFn = async () =>
|
|
143
142
|
BigInt(
|
|
144
|
-
await this._log.index.properties.index.sum(
|
|
145
|
-
new SumRequest({ key: "payloadSize" }),
|
|
146
|
-
),
|
|
143
|
+
await this._log.index.properties.index.sum({ key: "payloadSize" }),
|
|
147
144
|
);
|
|
148
145
|
|
|
149
146
|
// prune to max sum payload sizes in bytes
|