Skip to content

Commit

Permalink
REFACTOR Map cache code (pubkey#4604)
Browse files Browse the repository at this point in the history
* REFACTOR

* ADD getPrimaryKeyFromIndexableString()

* FIX lint
  • Loading branch information
pubkey authored Mar 30, 2023
1 parent 6e8ccbd commit a8776d7
Show file tree
Hide file tree
Showing 24 changed files with 491 additions and 441 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

<!-- CHANGELOG NEWEST -->

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

<!-- /CHANGELOG NEWEST -->
Expand Down
10 changes: 10 additions & 0 deletions src/custom-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,16 @@ export function getIndexStringLength<RxDocType>(
}


export function getPrimaryKeyFromIndexableString(
indexableString: string,
primaryKeyLength: number
): string {
const paddedPrimaryKey = indexableString.slice(primaryKeyLength * -1);
const primaryKey = paddedPrimaryKey.trimEnd();
return primaryKey;
}


export function getNumberIndexString(
parsedLengths: ParsedLengths,
fieldValue: number
Expand Down
4 changes: 2 additions & 2 deletions src/doc-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {
RxDocumentData
} from './types';
import {
getFromMapOrFill,
getFromMapOrCreate,
getFromMapOrThrow,
getHeightOfRevision
} from './plugins/utils';
Expand Down Expand Up @@ -109,7 +109,7 @@ export class DocumentCache<RxDocType, OrmMethods> {
public getCachedRxDocument(docData: RxDocumentData<RxDocType>): RxDocument<RxDocType, OrmMethods> {
const docId: string = (docData as any)[this.primaryPath];
const revisionHeight = getHeightOfRevision(docData._rev);
const cacheItem = getFromMapOrFill<string, CacheItem<RxDocType, OrmMethods>>(
const cacheItem = getFromMapOrCreate<string, CacheItem<RxDocType, OrmMethods>>(
this.cacheItemByDocId,
docId,
() => getNewCacheItem<RxDocType, OrmMethods>(docData)
Expand Down
106 changes: 54 additions & 52 deletions src/event-reduce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import { rxChangeEventToEventReduceChangeEvent } from './rx-change-event';
import {
arrayFilterNotEmpty,
clone,
ensureNotFalsy
ensureNotFalsy,
getFromMapOrCreate
} from './plugins/utils';
import { getQueryMatcher, getSortComparator, normalizeMangoQuery } from './rx-query-helper';

Expand Down Expand Up @@ -51,63 +52,64 @@ export const RXQUERY_QUERY_PARAMS_CACHE: WeakMap<RxQuery, QueryParams<any>> = ne
export function getQueryParams<RxDocType>(
rxQuery: RxQuery<RxDocType>
): QueryParams<RxDocType> {
if (!RXQUERY_QUERY_PARAMS_CACHE.has(rxQuery)) {
const collection = rxQuery.collection;
const normalizedMangoQuery = normalizeMangoQuery(
collection.storageInstance.schema,
clone(rxQuery.mangoQuery)
);
const primaryKey = collection.schema.primaryPath;
return getFromMapOrCreate(
RXQUERY_QUERY_PARAMS_CACHE,
rxQuery,
() => {
const collection = rxQuery.collection;
const normalizedMangoQuery = normalizeMangoQuery(
collection.storageInstance.schema,
clone(rxQuery.mangoQuery)
);
const primaryKey = collection.schema.primaryPath;

/**
* Create a custom sort comparator
* that uses the hooks to ensure
* we send for example compressed documents to be sorted by compressed queries.
*/
const sortComparator = getSortComparator(
collection.schema.jsonSchema,
normalizedMangoQuery
);
/**
* Create a custom sort comparator
* that uses the hooks to ensure
* we send for example compressed documents to be sorted by compressed queries.
*/
const sortComparator = getSortComparator(
collection.schema.jsonSchema,
normalizedMangoQuery
);

const useSortComparator: DeterministicSortComparator<RxDocType> = (docA: RxDocType, docB: RxDocType) => {
const sortComparatorData = {
docA,
docB,
rxQuery
const useSortComparator: DeterministicSortComparator<RxDocType> = (docA: RxDocType, docB: RxDocType) => {
const sortComparatorData = {
docA,
docB,
rxQuery
};
return sortComparator(sortComparatorData.docA, sortComparatorData.docB);
};
return sortComparator(sortComparatorData.docA, sortComparatorData.docB);
};

/**
* Create a custom query matcher
* that uses the hooks to ensure
* we send for example compressed documents to match compressed queries.
*/
const queryMatcher = getQueryMatcher(
collection.schema.jsonSchema,
normalizedMangoQuery
);
const useQueryMatcher: QueryMatcher<RxDocumentData<RxDocType>> = (doc: RxDocumentData<RxDocType>) => {
const queryMatcherData = {
doc,
rxQuery
/**
* Create a custom query matcher
* that uses the hooks to ensure
* we send for example compressed documents to match compressed queries.
*/
const queryMatcher = getQueryMatcher(
collection.schema.jsonSchema,
normalizedMangoQuery
);
const useQueryMatcher: QueryMatcher<RxDocumentData<RxDocType>> = (doc: RxDocumentData<RxDocType>) => {
const queryMatcherData = {
doc,
rxQuery
};
return queryMatcher(queryMatcherData.doc);
};
return queryMatcher(queryMatcherData.doc);
};

const ret: QueryParams<any> = {
primaryKey: rxQuery.collection.schema.primaryPath as any,
skip: normalizedMangoQuery.skip,
limit: normalizedMangoQuery.limit,
sortFields: getSortFieldsOfQuery(primaryKey, normalizedMangoQuery) as string[],
sortComparator: useSortComparator,
queryMatcher: useQueryMatcher
};
RXQUERY_QUERY_PARAMS_CACHE.set(rxQuery, ret);
return ret;
} else {
return RXQUERY_QUERY_PARAMS_CACHE.get(rxQuery) as QueryParams<RxDocType>;
}
const ret: QueryParams<any> = {
primaryKey: rxQuery.collection.schema.primaryPath as any,
skip: normalizedMangoQuery.skip,
limit: normalizedMangoQuery.limit,
sortFields: getSortFieldsOfQuery(primaryKey, normalizedMangoQuery) as string[],
sortComparator: useSortComparator,
queryMatcher: useQueryMatcher
};
return ret;
}
);
}


Expand Down
6 changes: 3 additions & 3 deletions src/incremental-write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type {
import {
clone,
ensureNotFalsy,
getFromMapOrFill,
getFromMapOrCreate,
getFromMapOrThrow,
parseRevision,
stripMetaDataFromDocument
Expand Down Expand Up @@ -62,7 +62,7 @@ export class IncrementalWriteQueue<RxDocType> {
modifier: IncrementalWriteModifier<RxDocType>
): Promise<RxDocumentData<RxDocType>> {
const docId: string = lastKnownDocumentState[this.primaryPath] as any;
const ar = getFromMapOrFill(this.queueByDocId, docId, () => []);
const ar = getFromMapOrCreate(this.queueByDocId, docId, () => []);
const ret = new Promise<RxDocumentData<RxDocType>>((resolve, reject) => {
const item: IncrementalWriteQueueItem<RxDocType> = {
lastKnownDocumentState,
Expand Down Expand Up @@ -157,7 +157,7 @@ export class IncrementalWriteQueue<RxDocType> {
const isConflict = isBulkWriteConflictError<RxDocType>(error);
if (isConflict) {
// had conflict -> retry afterwards
const ar = getFromMapOrFill(this.queueByDocId, docId, () => []);
const ar = getFromMapOrCreate(this.queueByDocId, docId, () => []);
/**
* Add the items back to this.queueByDocId
* by maintaining the original order.
Expand Down
22 changes: 11 additions & 11 deletions src/plugin-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type {
import {
defaultHashSha256,
flatClone,
getFromMapOrThrow,
getFromMapOrCreate,
requestIdleCallbackIfAvailable
} from './plugins/utils';
import { BehaviorSubject, firstValueFrom } from 'rxjs';
Expand Down Expand Up @@ -60,21 +60,21 @@ export function wrappedValidateStorageFactory(
*/
validatorKey: string
): WrappedStorageFunction {
if (!VALIDATOR_CACHE_BY_VALIDATOR_KEY.has(validatorKey)) {
VALIDATOR_CACHE_BY_VALIDATOR_KEY.set(validatorKey, new Map());
}
const VALIDATOR_CACHE = getFromMapOrThrow(VALIDATOR_CACHE_BY_VALIDATOR_KEY, validatorKey);
const VALIDATOR_CACHE = getFromMapOrCreate(
VALIDATOR_CACHE_BY_VALIDATOR_KEY,
validatorKey,
() => new Map()
);

function initValidator(
schema: RxJsonSchema<any>
): ValidatorFunction {
const hash = defaultHashSha256(JSON.stringify(schema));
if (!VALIDATOR_CACHE.has(hash)) {
const validator = getValidator(schema);
VALIDATOR_CACHE.set(hash, validator);
return validator;
}
return getFromMapOrThrow(VALIDATOR_CACHE, hash);
return getFromMapOrCreate(
VALIDATOR_CACHE,
hash,
() => getValidator(schema)
);
}

return (args) => {
Expand Down
15 changes: 6 additions & 9 deletions src/plugins/backup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
filter,
map
} from 'rxjs/operators';
import { newRxError } from '../../rx-error';
import type {
BackupOptions,
RxBackupWriteEvent,
Expand All @@ -20,7 +19,7 @@ import type {
RxPlugin
} from '../../types';
import {
getFromMapOrThrow,
getFromMapOrCreate,
PROMISE_RESOLVE_FALSE,
PROMISE_RESOLVE_TRUE,
PROMISE_RESOLVE_VOID
Expand Down Expand Up @@ -85,13 +84,11 @@ export async function backupSingleDocument(

const BACKUP_STATES_BY_DB: WeakMap<RxDatabase, RxBackupState[]> = new WeakMap();
function addToBackupStates(db: RxDatabase, state: RxBackupState) {
if (!BACKUP_STATES_BY_DB.has(db)) {
BACKUP_STATES_BY_DB.set(db, []);
}
const ar = getFromMapOrThrow(BACKUP_STATES_BY_DB, db);
if (!ar) {
throw newRxError('SNH');
}
const ar = getFromMapOrCreate(
BACKUP_STATES_BY_DB,
db,
() => []
);
ar.push(state);
}

Expand Down
Loading

0 comments on commit a8776d7

Please sign in to comment.