Skip to content

Commit a8776d7

Browse files
authored
REFACTOR Map cache code (pubkey#4604)
* REFACTOR * ADD getPrimaryKeyFromIndexableString() * FIX lint
1 parent 6e8ccbd commit a8776d7

File tree

24 files changed

+491
-441
lines changed

24 files changed

+491
-441
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
<!-- CHANGELOG NEWEST -->
55

6+
- ADD method `getPrimaryKeyFromIndexableString()`
7+
- REFACTOR utils for `Map` and `WeakMap` caching
68
<!-- ADD new changes here! -->
79

810
<!-- /CHANGELOG NEWEST -->

src/custom-index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@ export function getIndexStringLength<RxDocType>(
169169
}
170170

171171

172+
export function getPrimaryKeyFromIndexableString(
173+
indexableString: string,
174+
primaryKeyLength: number
175+
): string {
176+
const paddedPrimaryKey = indexableString.slice(primaryKeyLength * -1);
177+
const primaryKey = paddedPrimaryKey.trimEnd();
178+
return primaryKey;
179+
}
180+
181+
172182
export function getNumberIndexString(
173183
parsedLengths: ParsedLengths,
174184
fieldValue: number

src/doc-cache.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type {
44
RxDocumentData
55
} from './types';
66
import {
7-
getFromMapOrFill,
7+
getFromMapOrCreate,
88
getFromMapOrThrow,
99
getHeightOfRevision
1010
} from './plugins/utils';
@@ -109,7 +109,7 @@ export class DocumentCache<RxDocType, OrmMethods> {
109109
public getCachedRxDocument(docData: RxDocumentData<RxDocType>): RxDocument<RxDocType, OrmMethods> {
110110
const docId: string = (docData as any)[this.primaryPath];
111111
const revisionHeight = getHeightOfRevision(docData._rev);
112-
const cacheItem = getFromMapOrFill<string, CacheItem<RxDocType, OrmMethods>>(
112+
const cacheItem = getFromMapOrCreate<string, CacheItem<RxDocType, OrmMethods>>(
113113
this.cacheItemByDocId,
114114
docId,
115115
() => getNewCacheItem<RxDocType, OrmMethods>(docData)

src/event-reduce.ts

Lines changed: 54 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import { rxChangeEventToEventReduceChangeEvent } from './rx-change-event';
1919
import {
2020
arrayFilterNotEmpty,
2121
clone,
22-
ensureNotFalsy
22+
ensureNotFalsy,
23+
getFromMapOrCreate
2324
} from './plugins/utils';
2425
import { getQueryMatcher, getSortComparator, normalizeMangoQuery } from './rx-query-helper';
2526

@@ -51,63 +52,64 @@ export const RXQUERY_QUERY_PARAMS_CACHE: WeakMap<RxQuery, QueryParams<any>> = ne
5152
export function getQueryParams<RxDocType>(
5253
rxQuery: RxQuery<RxDocType>
5354
): QueryParams<RxDocType> {
54-
if (!RXQUERY_QUERY_PARAMS_CACHE.has(rxQuery)) {
55-
const collection = rxQuery.collection;
56-
const normalizedMangoQuery = normalizeMangoQuery(
57-
collection.storageInstance.schema,
58-
clone(rxQuery.mangoQuery)
59-
);
60-
const primaryKey = collection.schema.primaryPath;
55+
return getFromMapOrCreate(
56+
RXQUERY_QUERY_PARAMS_CACHE,
57+
rxQuery,
58+
() => {
59+
const collection = rxQuery.collection;
60+
const normalizedMangoQuery = normalizeMangoQuery(
61+
collection.storageInstance.schema,
62+
clone(rxQuery.mangoQuery)
63+
);
64+
const primaryKey = collection.schema.primaryPath;
6165

62-
/**
63-
* Create a custom sort comparator
64-
* that uses the hooks to ensure
65-
* we send for example compressed documents to be sorted by compressed queries.
66-
*/
67-
const sortComparator = getSortComparator(
68-
collection.schema.jsonSchema,
69-
normalizedMangoQuery
70-
);
66+
/**
67+
* Create a custom sort comparator
68+
* that uses the hooks to ensure
69+
* we send for example compressed documents to be sorted by compressed queries.
70+
*/
71+
const sortComparator = getSortComparator(
72+
collection.schema.jsonSchema,
73+
normalizedMangoQuery
74+
);
7175

72-
const useSortComparator: DeterministicSortComparator<RxDocType> = (docA: RxDocType, docB: RxDocType) => {
73-
const sortComparatorData = {
74-
docA,
75-
docB,
76-
rxQuery
76+
const useSortComparator: DeterministicSortComparator<RxDocType> = (docA: RxDocType, docB: RxDocType) => {
77+
const sortComparatorData = {
78+
docA,
79+
docB,
80+
rxQuery
81+
};
82+
return sortComparator(sortComparatorData.docA, sortComparatorData.docB);
7783
};
78-
return sortComparator(sortComparatorData.docA, sortComparatorData.docB);
79-
};
8084

81-
/**
82-
* Create a custom query matcher
83-
* that uses the hooks to ensure
84-
* we send for example compressed documents to match compressed queries.
85-
*/
86-
const queryMatcher = getQueryMatcher(
87-
collection.schema.jsonSchema,
88-
normalizedMangoQuery
89-
);
90-
const useQueryMatcher: QueryMatcher<RxDocumentData<RxDocType>> = (doc: RxDocumentData<RxDocType>) => {
91-
const queryMatcherData = {
92-
doc,
93-
rxQuery
85+
/**
86+
* Create a custom query matcher
87+
* that uses the hooks to ensure
88+
* we send for example compressed documents to match compressed queries.
89+
*/
90+
const queryMatcher = getQueryMatcher(
91+
collection.schema.jsonSchema,
92+
normalizedMangoQuery
93+
);
94+
const useQueryMatcher: QueryMatcher<RxDocumentData<RxDocType>> = (doc: RxDocumentData<RxDocType>) => {
95+
const queryMatcherData = {
96+
doc,
97+
rxQuery
98+
};
99+
return queryMatcher(queryMatcherData.doc);
94100
};
95-
return queryMatcher(queryMatcherData.doc);
96-
};
97101

98-
const ret: QueryParams<any> = {
99-
primaryKey: rxQuery.collection.schema.primaryPath as any,
100-
skip: normalizedMangoQuery.skip,
101-
limit: normalizedMangoQuery.limit,
102-
sortFields: getSortFieldsOfQuery(primaryKey, normalizedMangoQuery) as string[],
103-
sortComparator: useSortComparator,
104-
queryMatcher: useQueryMatcher
105-
};
106-
RXQUERY_QUERY_PARAMS_CACHE.set(rxQuery, ret);
107-
return ret;
108-
} else {
109-
return RXQUERY_QUERY_PARAMS_CACHE.get(rxQuery) as QueryParams<RxDocType>;
110-
}
102+
const ret: QueryParams<any> = {
103+
primaryKey: rxQuery.collection.schema.primaryPath as any,
104+
skip: normalizedMangoQuery.skip,
105+
limit: normalizedMangoQuery.limit,
106+
sortFields: getSortFieldsOfQuery(primaryKey, normalizedMangoQuery) as string[],
107+
sortComparator: useSortComparator,
108+
queryMatcher: useQueryMatcher
109+
};
110+
return ret;
111+
}
112+
);
111113
}
112114

113115

src/incremental-write.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import type {
1717
import {
1818
clone,
1919
ensureNotFalsy,
20-
getFromMapOrFill,
20+
getFromMapOrCreate,
2121
getFromMapOrThrow,
2222
parseRevision,
2323
stripMetaDataFromDocument
@@ -62,7 +62,7 @@ export class IncrementalWriteQueue<RxDocType> {
6262
modifier: IncrementalWriteModifier<RxDocType>
6363
): Promise<RxDocumentData<RxDocType>> {
6464
const docId: string = lastKnownDocumentState[this.primaryPath] as any;
65-
const ar = getFromMapOrFill(this.queueByDocId, docId, () => []);
65+
const ar = getFromMapOrCreate(this.queueByDocId, docId, () => []);
6666
const ret = new Promise<RxDocumentData<RxDocType>>((resolve, reject) => {
6767
const item: IncrementalWriteQueueItem<RxDocType> = {
6868
lastKnownDocumentState,
@@ -157,7 +157,7 @@ export class IncrementalWriteQueue<RxDocType> {
157157
const isConflict = isBulkWriteConflictError<RxDocType>(error);
158158
if (isConflict) {
159159
// had conflict -> retry afterwards
160-
const ar = getFromMapOrFill(this.queueByDocId, docId, () => []);
160+
const ar = getFromMapOrCreate(this.queueByDocId, docId, () => []);
161161
/**
162162
* Add the items back to this.queueByDocId
163163
* by maintaining the original order.

src/plugin-helpers.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import type {
2121
import {
2222
defaultHashSha256,
2323
flatClone,
24-
getFromMapOrThrow,
24+
getFromMapOrCreate,
2525
requestIdleCallbackIfAvailable
2626
} from './plugins/utils';
2727
import { BehaviorSubject, firstValueFrom } from 'rxjs';
@@ -60,21 +60,21 @@ export function wrappedValidateStorageFactory(
6060
*/
6161
validatorKey: string
6262
): WrappedStorageFunction {
63-
if (!VALIDATOR_CACHE_BY_VALIDATOR_KEY.has(validatorKey)) {
64-
VALIDATOR_CACHE_BY_VALIDATOR_KEY.set(validatorKey, new Map());
65-
}
66-
const VALIDATOR_CACHE = getFromMapOrThrow(VALIDATOR_CACHE_BY_VALIDATOR_KEY, validatorKey);
63+
const VALIDATOR_CACHE = getFromMapOrCreate(
64+
VALIDATOR_CACHE_BY_VALIDATOR_KEY,
65+
validatorKey,
66+
() => new Map()
67+
);
6768

6869
function initValidator(
6970
schema: RxJsonSchema<any>
7071
): ValidatorFunction {
7172
const hash = defaultHashSha256(JSON.stringify(schema));
72-
if (!VALIDATOR_CACHE.has(hash)) {
73-
const validator = getValidator(schema);
74-
VALIDATOR_CACHE.set(hash, validator);
75-
return validator;
76-
}
77-
return getFromMapOrThrow(VALIDATOR_CACHE, hash);
73+
return getFromMapOrCreate(
74+
VALIDATOR_CACHE,
75+
hash,
76+
() => getValidator(schema)
77+
);
7878
}
7979

8080
return (args) => {

src/plugins/backup/index.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
filter,
1111
map
1212
} from 'rxjs/operators';
13-
import { newRxError } from '../../rx-error';
1413
import type {
1514
BackupOptions,
1615
RxBackupWriteEvent,
@@ -20,7 +19,7 @@ import type {
2019
RxPlugin
2120
} from '../../types';
2221
import {
23-
getFromMapOrThrow,
22+
getFromMapOrCreate,
2423
PROMISE_RESOLVE_FALSE,
2524
PROMISE_RESOLVE_TRUE,
2625
PROMISE_RESOLVE_VOID
@@ -85,13 +84,11 @@ export async function backupSingleDocument(
8584

8685
const BACKUP_STATES_BY_DB: WeakMap<RxDatabase, RxBackupState[]> = new WeakMap();
8786
function addToBackupStates(db: RxDatabase, state: RxBackupState) {
88-
if (!BACKUP_STATES_BY_DB.has(db)) {
89-
BACKUP_STATES_BY_DB.set(db, []);
90-
}
91-
const ar = getFromMapOrThrow(BACKUP_STATES_BY_DB, db);
92-
if (!ar) {
93-
throw newRxError('SNH');
94-
}
87+
const ar = getFromMapOrCreate(
88+
BACKUP_STATES_BY_DB,
89+
db,
90+
() => []
91+
);
9592
ar.push(state);
9693
}
9794

0 commit comments

Comments
 (0)