Skip to content

Commit 9741d09

Browse files
committed
Re-use more equality implementations.
1 parent 6eedfd0 commit 9741d09

2 files changed

Lines changed: 77 additions & 77 deletions

File tree

packages/sync-rules/src/sync_plan/evaluator/bucket_data_source.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
import { SqlExpression } from '../expression.js';
2121
import { ExpressionToSqlite } from '../expression_to_sql.js';
2222
import * as plan from '../plan.js';
23-
import { hashStreamBucketDataSource, streamBucketDataSourcesEqual } from '../plan_equality.js';
23+
import { streamBucketDataSourceEquality } from '../plan_equality.js';
2424
import { SyncPlanSchemaAnalyzer } from '../schema_inference.js';
2525
import { StreamEvaluationContext } from './index.js';
2626
import { TableProcessorToSqlHelper } from './table_processor_to_sql.js';
@@ -52,11 +52,11 @@ export class PreparedStreamBucketDataSource implements BucketDataSource {
5252
if (!(other instanceof PreparedStreamBucketDataSource)) {
5353
return false;
5454
}
55-
return streamBucketDataSourcesEqual(this.source, other.source);
55+
return streamBucketDataSourceEquality.equals(this.source, other.source);
5656
}
5757

5858
buildHash(hasher: StableHasher): void {
59-
hashStreamBucketDataSource(hasher, this.source);
59+
streamBucketDataSourceEquality.hash(hasher, this.source);
6060
}
6161

6262
get bucketParameters(): string[] {

packages/sync-rules/src/sync_plan/plan_equality.ts

Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -13,58 +13,41 @@ import {
1313
TableProcessorTableValuedFunctionOutput
1414
} from './plan.js';
1515

16-
export function streamBucketDataSourcesEqual(a: StreamBucketDataSource, b: StreamBucketDataSource): boolean {
17-
if (a === b) {
18-
return true;
16+
export const streamBucketDataSourceEquality: Equality<StreamBucketDataSource> = {
17+
hash(hasher, value) {
18+
hasher.addHash(value.hashCode);
19+
},
20+
equals(a, b) {
21+
return a === b || (a.hashCode == b.hashCode && streamDataSourceSetEquality.equals(a.sources, b.sources));
1922
}
23+
};
2024

21-
return a.hashCode == b.hashCode && streamDataSourceSetEquality.equals(a.sources, b.sources);
22-
}
23-
24-
export function hashStreamBucketDataSource(hasher: StableHasher, source: StreamBucketDataSource): void {
25-
hasher.addHash(source.hashCode);
26-
streamDataSourceSetEquality.hash(hasher, source.sources);
27-
}
28-
29-
const streamDataSourceEquality: Equality<StreamDataSource> = {
30-
equals: streamDataSourcesEqual,
31-
hash: hashStreamDataSource
25+
export const streamDataSourceEquality: Equality<StreamDataSource> = {
26+
hash(hasher, value) {
27+
hasher.addHash(value.hashCode);
28+
},
29+
equals(a, b) {
30+
return (
31+
a === b ||
32+
(tableProcessorsEqual(a, b) &&
33+
a.outputTableName == b.outputTableName &&
34+
columnSourceListEquality(a, b).equals(a.columns, b.columns))
35+
);
36+
}
3237
};
3338

3439
const streamDataSourceSetEquality = unorderedEquality(streamDataSourceEquality);
3540

36-
function streamDataSourcesEqual(a: StreamDataSource, b: StreamDataSource): boolean {
37-
return (
38-
tableProcessorsEqual(a, b) &&
39-
a.outputTableName == b.outputTableName &&
40-
listEquals(a.columns, b.columns, (left, right) => columnSourcesEqual(left, right, a, b))
41-
);
42-
}
43-
44-
function hashStreamDataSource(hasher: StableHasher, source: StreamDataSource): void {
45-
hashTableProcessor(hasher, source);
46-
hashOptionalString(hasher, source.outputTableName);
47-
hashList(hasher, source.columns, (nested, column) => hashColumnSource(nested, column, source));
48-
}
49-
5041
function tableProcessorsEqual(a: TableProcessor, b: TableProcessor): boolean {
5142
return (
5243
a.hashCode == b.hashCode &&
5344
a.sourceTable.equals(b.sourceTable) &&
5445
tableValuedFunctionListEquality.equals(a.tableValuedFunctions, b.tableValuedFunctions) &&
55-
listEquals(a.filters, b.filters, (left, right) => expressionsEqual(left, right, a, b)) &&
56-
listEquals(a.parameters, b.parameters, (left, right) => expressionsEqual(left.expr, right.expr, a, b))
46+
expressionListEquality(a, b).equals(a.filters, b.filters) &&
47+
partitionKeyListEquality(a, b).equals(a.parameters, b.parameters)
5748
);
5849
}
5950

60-
function hashTableProcessor(hasher: StableHasher, source: TableProcessor): void {
61-
hasher.addHash(source.hashCode);
62-
source.sourceTable.buildHash(hasher);
63-
tableValuedFunctionListEquality.hash(hasher, source.tableValuedFunctions);
64-
hashList(hasher, source.filters, (nested, expression) => hashExpression(nested, expression, source));
65-
hashList(hasher, source.parameters, (nested, parameter) => hashExpression(nested, parameter.expr, source));
66-
}
67-
6851
const tableValuedFunctionEquality: Equality<TableProcessorTableValuedFunction> = {
6952
equals(a, b) {
7053
return (
@@ -82,27 +65,29 @@ function hashTableValuedFunction(hasher: StableHasher, fn: TableProcessorTableVa
8265
columnParameterExpressionListEquality.hash(hasher, fn.functionInputs);
8366
}
8467

85-
function columnSourcesEqual(
86-
a: ColumnSource,
87-
b: ColumnSource,
88-
sourceA: TableProcessor,
89-
sourceB: TableProcessor
90-
): boolean {
91-
if (a == 'star' || b == 'star') {
92-
return a == b;
93-
}
94-
95-
return a.alias == b.alias && expressionsEqual(a.expr, b.expr, sourceA, sourceB);
68+
function columnSourceEquality(sourceA: TableProcessor, sourceB: TableProcessor): Equality<ColumnSource> {
69+
return {
70+
hash(hasher, value) {
71+
if (value == 'star') {
72+
hasher.addHash(0);
73+
} else {
74+
hasher.addHash(1);
75+
hasher.addString(value.alias);
76+
hashExpression(hasher, value.expr, sourceA);
77+
}
78+
},
79+
equals(a, b) {
80+
if (a == 'star' || b == 'star') {
81+
return a == b;
82+
}
83+
84+
return a.alias == b.alias && expressionsEqual(a.expr, b.expr, sourceA, sourceB);
85+
}
86+
};
9687
}
9788

98-
function hashColumnSource(hasher: StableHasher, column: ColumnSource, source: TableProcessor): void {
99-
if (column == 'star') {
100-
hasher.addHash(0);
101-
} else {
102-
hasher.addHash(1);
103-
hasher.addString(column.alias);
104-
hashExpression(hasher, column.expr, source);
105-
}
89+
function columnSourceListEquality(sourceA: TableProcessor, sourceB: TableProcessor): Equality<Iterable<ColumnSource>> {
90+
return listEquality(columnSourceEquality(sourceA, sourceB));
10691
}
10792

10893
const columnParameterExpressionEquality: Equality<SqlExpression<ColumnSqlParameterValue>> = {
@@ -143,6 +128,38 @@ function hashExpression(
143128
planInputListEquality.hash(hasher, expressionInputs(expression, source));
144129
}
145130

131+
function expressionEquality(
132+
sourceA: TableProcessor,
133+
sourceB: TableProcessor
134+
): Equality<SqlExpression<TableProcessorData>> {
135+
return {
136+
hash(hasher, value) {
137+
hashExpression(hasher, value, sourceA);
138+
},
139+
equals(a, b) {
140+
return expressionsEqual(a, b, sourceA, sourceB);
141+
}
142+
};
143+
}
144+
145+
function expressionListEquality(
146+
sourceA: TableProcessor,
147+
sourceB: TableProcessor
148+
): Equality<Iterable<SqlExpression<TableProcessorData>>> {
149+
return listEquality(expressionEquality(sourceA, sourceB));
150+
}
151+
152+
function partitionKeyListEquality(sourceA: TableProcessor, sourceB: TableProcessor) {
153+
return listEquality({
154+
hash(hasher, value: { expr: SqlExpression<TableProcessorData> }) {
155+
hashExpression(hasher, value.expr, sourceA);
156+
},
157+
equals(a: { expr: SqlExpression<TableProcessorData> }, b: { expr: SqlExpression<TableProcessorData> }) {
158+
return expressionsEqual(a.expr, b.expr, sourceA, sourceB);
159+
}
160+
});
161+
}
162+
146163
type PlanExpressionInput =
147164
| { type: 'column'; column: string }
148165
| { type: 'function'; functionIndex: number; outputName: string };
@@ -247,20 +264,3 @@ class FindColumnInputs extends RecursiveExpressionVisitor<ColumnSqlParameterValu
247264
function isTableValuedFunctionOutput(value: TableProcessorData): value is TableProcessorTableValuedFunctionOutput {
248265
return 'function' in value;
249266
}
250-
251-
function listEquals<T>(a: readonly T[], b: readonly T[], equals: (a: T, b: T) => boolean): boolean {
252-
return listEquality({ equals, hash: () => {} }).equals(a, b);
253-
}
254-
255-
function hashList<T>(hasher: StableHasher, values: readonly T[], hash: (hasher: StableHasher, value: T) => void) {
256-
listEquality({ equals: Object.is, hash }).hash(hasher, values);
257-
}
258-
259-
function hashOptionalString(hasher: StableHasher, value: string | undefined): void {
260-
if (value == null) {
261-
hasher.addHash(0);
262-
} else {
263-
hasher.addHash(1);
264-
hasher.addString(value);
265-
}
266-
}

0 commit comments

Comments
 (0)