Skip to content

Tree-Shake Path #4477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/database/src/api/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import { fatal } from '../core/util/util';
import { parseRepoInfo } from '../core/util/libs/parser';
import { Path } from '../core/util/Path';
import { newEmptyPath } from '../core/util/Path';
import { Reference } from './Reference';
import { Repo } from '../core/Repo';
import { RepoManager } from '../core/RepoManager';
Expand Down Expand Up @@ -79,7 +79,7 @@ export class Database implements FirebaseService {

get root_(): Reference {
if (!this.rootInternal_) {
this.rootInternal_ = new Reference(this.repo_, Path.Empty);
this.rootInternal_ = new Reference(this.repo_, newEmptyPath());
}

return this.rootInternal_;
Expand Down
27 changes: 16 additions & 11 deletions packages/database/src/api/Query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,35 @@

import {
assert,
Deferred,
errorPrefix,
validateArgCount,
validateCallback,
validateContextObject,
Deferred
validateContextObject
} from '@firebase/util';
import { KEY_INDEX } from '../core/snap/indexes/KeyIndex';
import { PRIORITY_INDEX } from '../core/snap/indexes/PriorityIndex';
import { VALUE_INDEX } from '../core/snap/indexes/ValueIndex';
import { PathIndex } from '../core/snap/indexes/PathIndex';
import { MIN_NAME, MAX_NAME, ObjectToUniqueKey } from '../core/util/util';
import { Path } from '../core/util/Path';
import { MAX_NAME, MIN_NAME, ObjectToUniqueKey } from '../core/util/util';
import {
Path,
pathEquals,
pathIsEmpty,
pathToUrlEncodedString
} from '../core/util/Path';
import {
isValidPriority,
validateEventType,
validatePathString,
validateFirebaseDataArg,
validateKey
validateKey,
validatePathString
} from '../core/util/validation';

import {
ValueEventRegistration,
ChildEventRegistration,
EventRegistration
EventRegistration,
ValueEventRegistration
} from '../core/view/EventRegistration';

import { Repo } from '../core/Repo';
Expand Down Expand Up @@ -405,7 +410,7 @@ export class Query {
validatePathString('Query.orderByChild', 1, path, false);
this.validateNoPreviousOrderByCall_('Query.orderByChild');
const parsedPath = new Path(path);
if (parsedPath.isEmpty()) {
if (pathIsEmpty(parsedPath)) {
throw new Error(
'Query.orderByChild: cannot pass in empty path. Use Query.orderByValue() instead.'
);
Expand Down Expand Up @@ -569,7 +574,7 @@ export class Query {
toString(): string {
validateArgCount('Query.toString', 0, 0, arguments.length);

return this.repo.toString() + this.path.toUrlEncodedString();
return this.repo.toString() + pathToUrlEncodedString(this.path);
}

// Do not create public documentation. This is intended to make JSON serialization work but is otherwise unnecessary
Expand Down Expand Up @@ -605,7 +610,7 @@ export class Query {
}

const sameRepo = this.repo === other.repo;
const samePath = this.path.equals(other.path);
const samePath = pathEquals(this.path, other.path);
const sameQueryIdentifier =
this.queryIdentifier() === other.queryIdentifier();

Expand Down
21 changes: 14 additions & 7 deletions packages/database/src/api/Reference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ import { warn } from '../core/util/util';
import { nextPushId } from '../core/util/NextPushId';
import { Query } from './Query';
import { Repo } from '../core/Repo';
import { Path } from '../core/util/Path';
import {
Path,
pathChild,
pathGetBack,
pathGetFront,
pathIsEmpty,
pathParent
} from '../core/util/Path';
import { QueryParams } from '../core/view/QueryParams';
import {
validateBoolean,
Expand Down Expand Up @@ -68,10 +75,10 @@ export class Reference extends Query {
getKey(): string | null {
validateArgCount('Reference.key', 0, 0, arguments.length);

if (this.path.isEmpty()) {
if (pathIsEmpty(this.path)) {
return null;
} else {
return this.path.getBack();
return pathGetBack(this.path);
}
}

Expand All @@ -80,21 +87,21 @@ export class Reference extends Query {
if (typeof pathString === 'number') {
pathString = String(pathString);
} else if (!(pathString instanceof Path)) {
if (this.path.getFront() === null) {
if (pathGetFront(this.path) === null) {
validateRootPathString('Reference.child', 1, pathString, false);
} else {
validatePathString('Reference.child', 1, pathString, false);
}
}

return new Reference(this.repo, this.path.child(pathString));
return new Reference(this.repo, pathChild(this.path, pathString));
}

/** @return {?Reference} */
getParent(): Reference | null {
validateArgCount('Reference.parent', 0, 0, arguments.length);

const parentPath = this.path.parent();
const parentPath = pathParent(this.path);
return parentPath === null ? null : new Reference(this.repo, parentPath);
}

Expand Down Expand Up @@ -278,7 +285,7 @@ export class Reference extends Query {

const deferred = new Deferred();
this.repo.setWithPriority(
this.path.child('.priority'),
pathChild(this.path, '.priority'),
priority,
null,
deferred.wrapCallback(onComplete)
Expand Down
33 changes: 23 additions & 10 deletions packages/database/src/core/CompoundWrite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@
*/

import { ImmutableTree } from './util/ImmutableTree';
import { Path } from './util/Path';
import {
newEmptyPath,
newRelativePath,
Path,
pathChild,
pathIsEmpty
} from './util/Path';
import { NamedNode, Node } from './snap/Node';
import { PRIORITY_INDEX } from './snap/indexes/PriorityIndex';
import { assert } from '@firebase/util';
Expand All @@ -42,14 +48,14 @@ export function compoundWriteAddWrite(
path: Path,
node: Node
): CompoundWrite {
if (path.isEmpty()) {
if (pathIsEmpty(path)) {
return new CompoundWrite(new ImmutableTree(node));
} else {
const rootmost = compoundWrite.writeTree_.findRootMostValueAndPath(path);
if (rootmost != null) {
const rootMostPath = rootmost.path;
let value = rootmost.value;
const relativePath = Path.relativePath(rootMostPath, path);
const relativePath = newRelativePath(rootMostPath, path);
value = value.updateChild(relativePath, node);
return new CompoundWrite(
compoundWrite.writeTree_.set(rootMostPath, value)
Expand All @@ -69,7 +75,7 @@ export function compoundWriteAddWrites(
): CompoundWrite {
let newWrite = compoundWrite;
each(updates, (childKey: string, node: Node) => {
newWrite = compoundWriteAddWrite(newWrite, path.child(childKey), node);
newWrite = compoundWriteAddWrite(newWrite, pathChild(path, childKey), node);
});
return newWrite;
}
Expand All @@ -86,7 +92,7 @@ export function compoundWriteRemoveWrite(
compoundWrite: CompoundWrite,
path: Path
): CompoundWrite {
if (path.isEmpty()) {
if (pathIsEmpty(path)) {
return CompoundWrite.empty();
} else {
const newWriteTree = compoundWrite.writeTree_.setTree(
Expand Down Expand Up @@ -128,7 +134,7 @@ export function compoundWriteGetCompleteNode(
if (rootmost != null) {
return compoundWrite.writeTree_
.get(rootmost.path)
.getChild(Path.relativePath(rootmost.path, path));
.getChild(newRelativePath(rootmost.path, path));
} else {
return null;
}
Expand Down Expand Up @@ -171,7 +177,7 @@ export function compoundWriteChildCompoundWrite(
compoundWrite: CompoundWrite,
path: Path
): CompoundWrite {
if (path.isEmpty()) {
if (pathIsEmpty(path)) {
return compoundWrite;
} else {
const shadowingNode = compoundWriteGetCompleteNode(compoundWrite, path);
Expand Down Expand Up @@ -201,7 +207,7 @@ export function compoundWriteApply(
compoundWrite: CompoundWrite,
node: Node
): Node {
return applySubtreeWrite(Path.Empty, compoundWrite.writeTree_, node);
return applySubtreeWrite(newEmptyPath(), compoundWrite.writeTree_, node);
}

function applySubtreeWrite(
Expand All @@ -224,12 +230,19 @@ function applySubtreeWrite(
);
priorityWrite = childTree.value;
} else {
node = applySubtreeWrite(relativePath.child(childKey), childTree, node);
node = applySubtreeWrite(
pathChild(relativePath, childKey),
childTree,
node
);
}
});
// If there was a priority write, we only apply it if the node is not empty
if (!node.getChild(relativePath).isEmpty() && priorityWrite !== null) {
node = node.updateChild(relativePath.child('.priority'), priorityWrite);
node = node.updateChild(
pathChild(relativePath, '.priority'),
priorityWrite
);
}
return node;
}
Expand Down
44 changes: 30 additions & 14 deletions packages/database/src/core/Repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ import {
resolveDeferredValueTree
} from './util/ServerValues';
import { nodeFromJSON } from './snap/nodeFromJSON';
import { Path } from './util/Path';
import {
newEmptyPath,
newRelativePath,
Path,
pathChild,
pathGetFront,
pathPopFront
} from './util/Path';
import { SparseSnapshotTree } from './SparseSnapshotTree';
import { SyncTree } from './SyncTree';
import { SnapshotHolder } from './SnapshotHolder';
Expand Down Expand Up @@ -496,7 +503,7 @@ export class Repo {
each(childrenToMerge, (changedKey: string, changedValue: unknown) => {
empty = false;
changedChildren[changedKey] = resolveDeferredValueTree(
path.child(changedKey),
pathChild(path, changedKey),
nodeFromJSON(changedValue),
this.serverSyncTree_,
serverValues
Expand Down Expand Up @@ -536,7 +543,9 @@ export class Repo {
);

each(childrenToMerge, (changedPath: string) => {
const affectedPath = this.abortTransactions_(path.child(changedPath));
const affectedPath = this.abortTransactions_(
pathChild(path, changedPath)
);
this.rerunTransactions_(affectedPath);
});

Expand All @@ -556,7 +565,7 @@ export class Repo {

const serverValues = this.generateServerValues();
const resolvedOnDisconnectTree = new SparseSnapshotTree();
this.onDisconnect_.forEachTree(Path.Empty, (path, node) => {
this.onDisconnect_.forEachTree(newEmptyPath(), (path, node) => {
const resolved = resolveDeferredValueTree(
path,
node,
Expand All @@ -567,7 +576,7 @@ export class Repo {
});
let events: Event[] = [];

resolvedOnDisconnectTree.forEachTree(Path.Empty, (path, snap) => {
resolvedOnDisconnectTree.forEachTree(newEmptyPath(), (path, snap) => {
events = events.concat(
this.serverSyncTree_.applyServerOverwrite(path, snap)
);
Expand All @@ -576,7 +585,11 @@ export class Repo {
});

this.onDisconnect_ = new SparseSnapshotTree();
eventQueueRaiseEventsForChangedPath(this.eventQueue_, Path.Empty, events);
eventQueueRaiseEventsForChangedPath(
this.eventQueue_,
newEmptyPath(),
events
);
}

onDisconnectCancel(
Expand Down Expand Up @@ -648,7 +661,10 @@ export class Repo {
if (status === 'ok') {
each(childrenToMerge, (childName: string, childNode: unknown) => {
const newChildNode = nodeFromJSON(childNode);
this.onDisconnect_.remember(path.child(childName), newChildNode);
this.onDisconnect_.remember(
pathChild(path, childName),
newChildNode
);
});
}
this.callOnCompleteCallback(onComplete, status, errorReason);
Expand All @@ -658,7 +674,7 @@ export class Repo {

addEventCallbackForQuery(query: Query, eventRegistration: EventRegistration) {
let events;
if (query.path.getFront() === '.info') {
if (pathGetFront(query.path) === '.info') {
events = this.infoSyncTree_.addEventRegistration(
query,
eventRegistration
Expand All @@ -679,7 +695,7 @@ export class Repo {
// These are guaranteed not to raise events, since we're not passing in a cancelError. However, we can future-proof
// a little bit by handling the return values anyways.
let events;
if (query.path.getFront() === '.info') {
if (pathGetFront(query.path) === '.info') {
events = this.infoSyncTree_.removeEventRegistration(
query,
eventRegistration
Expand Down Expand Up @@ -978,7 +994,7 @@ export class Repo {
);
txn.status = TransactionStatus.SENT;
txn.retryCount++;
const relativePath = Path.relativePath(path, txn.path);
const relativePath = newRelativePath(path, txn.path);
// If we've gotten to this point, the output snapshot must be defined.
snapToSend = snapToSend.updateChild(
relativePath /** @type {!Node} */,
Expand Down Expand Up @@ -1112,7 +1128,7 @@ export class Repo {
});
for (let i = 0; i < queue.length; i++) {
const transaction = queue[i];
const relativePath = Path.relativePath(path, transaction.path);
const relativePath = newRelativePath(path, transaction.path);
let abortTransaction = false,
abortReason;
assert(
Expand Down Expand Up @@ -1258,11 +1274,11 @@ export class Repo {
// Start at the root and walk deeper into the tree towards path until we
// find a node with pending transactions.
let transactionNode = this.transactionQueueTree_;
front = path.getFront();
front = pathGetFront(path);
while (front !== null && transactionNode.getValue() === null) {
transactionNode = transactionNode.subTree(front);
path = path.popFront();
front = path.getFront();
path = pathPopFront(path);
front = pathGetFront(path);
}

return transactionNode;
Expand Down
3 changes: 2 additions & 1 deletion packages/database/src/core/RepoManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
EmulatorAdminTokenProvider,
FirebaseAuthTokenProvider
} from './AuthTokenProvider';
import { pathIsEmpty } from './util/Path';

/**
* This variable is also defined in the firebase node.js admin SDK. Before
Expand Down Expand Up @@ -155,7 +156,7 @@ export class RepoManager {
: new FirebaseAuthTokenProvider(app, authProvider);

validateUrl('Invalid Firebase Database URL', 1, parsedUrl);
if (!parsedUrl.path.isEmpty()) {
if (!pathIsEmpty(parsedUrl.path)) {
fatal(
'Database URL must point to the root of a Firebase Database ' +
'(not including a child path).'
Expand Down
Loading