Skip to content

Revert: Add Database.Servervalue.increment(x) #2500

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 3 commits into from
Jan 7, 2020
Merged
Show file tree
Hide file tree
Changes from 2 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
7 changes: 0 additions & 7 deletions packages/database/src/api/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,6 @@ export class Database implements FirebaseService {
static readonly ServerValue = {
TIMESTAMP: {
'.sv': 'timestamp'
},
_increment: (x: number) => {
return {
'.sv': {
'increment': x
}
};
}
};

Expand Down
4 changes: 0 additions & 4 deletions packages/database/src/core/Repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,8 @@ export class Repo {
// (b) store unresolved paths on JSON parse
const serverValues = this.generateServerValues();
const newNodeUnresolved = nodeFromJSON(newVal, newPriority);
const existing = this.serverSyncTree_.calcCompleteEventCache(path);
const newNode = resolveDeferredValueSnapshot(
newNodeUnresolved,
existing,
serverValues
);

Expand Down Expand Up @@ -367,7 +365,6 @@ export class Repo {
const newNodeUnresolved = nodeFromJSON(changedValue);
changedChildren[changedKey] = resolveDeferredValueSnapshot(
newNodeUnresolved,
this.serverSyncTree_.calcCompleteEventCache(path),
serverValues
);
});
Expand Down Expand Up @@ -422,7 +419,6 @@ export class Repo {
const serverValues = this.generateServerValues();
const resolvedOnDisconnectTree = resolveDeferredValueTree(
this.onDisconnect_,
this.serverSyncTree_,
serverValues
);
let events: Event[] = [];
Expand Down
2 changes: 0 additions & 2 deletions packages/database/src/core/Repo_transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ Repo.prototype.startTransaction = function(
const newNodeUnresolved = nodeFromJSON(newVal, priorityForNode);
const newNode = resolveDeferredValueSnapshot(
newNodeUnresolved,
currentState,
serverValues
);
transaction.currentOutputSnapshotRaw = newNodeUnresolved;
Expand Down Expand Up @@ -534,7 +533,6 @@ Repo.prototype.startTransaction = function(
const serverValues = this.generateServerValues();
const newNodeResolved = resolveDeferredValueSnapshot(
newDataNode,
currentNode,
serverValues
);

Expand Down
11 changes: 6 additions & 5 deletions packages/database/src/core/SyncTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,17 +474,18 @@ export class SyncTree {
}

/**
* Returns a complete cache, if we have one, of the data at a particular path. If the location does not have a
* listener above it, we will get a false "null". This shouldn't be a problem because transactions will always
* have a listener above, and atomic operations would correctly show a jitter of <increment value> ->
* <incremented total> as the write is applied locally and then acknowledged at the server.
* Returns a complete cache, if we have one, of the data at a particular path. The location must have a listener above
* it, but as this is only used by transaction code, that should always be the case anyways.
*
* Note: this method will *include* hidden writes from transaction with applyLocally set to false.
*
* @param path The path to the data we want
* @param writeIdsToExclude A specific set to be excluded
*/
calcCompleteEventCache(path: Path, writeIdsToExclude?: number[]): Node {
calcCompleteEventCache(
path: Path,
writeIdsToExclude?: number[]
): Node | null {
const includeHiddenSets = true;
const writeTree = this.pendingWriteTree_;
const serverCache = this.syncPointTree_.findOnPath(
Expand Down
83 changes: 10 additions & 73 deletions packages/database/src/core/util/ServerValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { nodeFromJSON } from '../snap/nodeFromJSON';
import { PRIORITY_INDEX } from '../snap/indexes/PriorityIndex';
import { Node } from '../snap/Node';
import { ChildrenNode } from '../snap/ChildrenNode';
import { SyncTree } from '../SyncTree';
import { Indexable } from './misc';

/**
Expand All @@ -49,65 +48,19 @@ export const generateWithValues = function(
* @return {!(string|number|boolean)}
*/
export const resolveDeferredValue = function(
value: { [k: string]: unknown } | string | number | boolean,
existing: Node,
serverValues: { [k: string]: unknown }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
value: { [k: string]: any } | string | number | boolean,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
serverValues: { [k: string]: any }
): string | number | boolean {
if (!value || typeof value !== 'object') {
return value as string | number | boolean;
}
assert('.sv' in value, 'Unexpected leaf node or priority contents');

if (typeof value['.sv'] === 'string') {
return resolveScalarDeferredValue(value['.sv'], existing, serverValues);
} else if (typeof value['.sv'] === 'object') {
return resolveComplexDeferredValue(value['.sv'], existing, serverValues);
} else {
assert(false, 'Unexpected server value: ' + JSON.stringify(value, null, 2));
return serverValues[value['.sv']];
}
};

const resolveScalarDeferredValue = function(
op: string,
existing: Node,
serverValues: { [k: string]: unknown }
): string | number | boolean {
switch (op) {
case 'timestamp':
return serverValues['timestamp'] as string | number | boolean;
default:
assert(false, 'Unexpected server value: ' + op);
}
};

const resolveComplexDeferredValue = function(
op: object,
existing: Node,
unused: { [k: string]: unknown }
): string | number | boolean {
if (!op.hasOwnProperty('increment')) {
assert(false, 'Unexpected server value: ' + JSON.stringify(op, null, 2));
}
const delta = op['increment'];
if (typeof delta !== 'number') {
assert(false, 'Unexpected increment value: ' + delta);
}

// Incrementing a non-number sets the value to the incremented amount
if (!existing.isLeafNode()) {
return delta;
}

const leaf = existing as LeafNode;
const existingVal = leaf.getValue();
if (typeof existingVal !== 'number') {
return delta;
}

// No need to do over/underflow arithmetic here because JS only handles floats under the covers
return existingVal + delta;
};

/**
* Recursively replace all deferred values and priorities in the tree with the
* specified generated replacement values.
Expand All @@ -117,19 +70,13 @@ const resolveComplexDeferredValue = function(
*/
export const resolveDeferredValueTree = function(
tree: SparseSnapshotTree,
syncTree: SyncTree,
serverValues: Indexable
serverValues: object
): SparseSnapshotTree {
const resolvedTree = new SparseSnapshotTree();
tree.forEachTree(new Path(''), (path, node) => {
const existing = syncTree.calcCompleteEventCache(path);
assert(
existing !== null && typeof existing !== 'undefined',
'Expected ChildrenNode.EMPTY_NODE for nulls'
);
resolvedTree.remember(
path,
resolveDeferredValueSnapshot(node, existing, serverValues)
resolveDeferredValueSnapshot(node, serverValues)
);
});
return resolvedTree;
Expand All @@ -145,29 +92,20 @@ export const resolveDeferredValueTree = function(
*/
export const resolveDeferredValueSnapshot = function(
node: Node,
existing: Node,
serverValues: Indexable
serverValues: object
): Node {
const rawPri = node.getPriority().val() as
| Indexable
| boolean
| null
| number
| string;
const priority = resolveDeferredValue(
rawPri,
existing.getPriority(),
serverValues
);
const priority = resolveDeferredValue(rawPri, serverValues);
let newNode: Node;

if (node.isLeafNode()) {
const leafNode = node as LeafNode;
const value = resolveDeferredValue(
leafNode.getValue(),
existing,
serverValues
);
const value = resolveDeferredValue(leafNode.getValue(), serverValues);
if (
value !== leafNode.getValue() ||
priority !== leafNode.getPriority().val()
Expand All @@ -185,7 +123,6 @@ export const resolveDeferredValueSnapshot = function(
childrenNode.forEachChild(PRIORITY_INDEX, (childName, childNode) => {
const newChildNode = resolveDeferredValueSnapshot(
childNode,
existing.getImmediateChild(childName),
serverValues
);
if (newChildNode !== childNode) {
Expand Down
96 changes: 0 additions & 96 deletions packages/database/test/servervalues.test.ts

This file was deleted.