Skip to content

Commit e8a091a

Browse files
authored
Merge pull request #181 from dev-five-git/improve-performance
Improve performance
2 parents b5a17d5 + dcc4eb6 commit e8a091a

238 files changed

Lines changed: 7929 additions & 8272 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.cargo/mutants.toml‎

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,15 @@ exclude_re = [
7575
# column x-range rather than sitting side-by-side. Therefore both mutants
7676
# are byte-identical for every renderer-reachable layout while the other
7777
# pick_anchors arithmetic remains in scope.
78-
"edges[.]rs:152(:[0-9]+)?: replace > with >= in pick_anchors",
78+
"edges[.]rs:[0-9]+:[0-9]+: replace > with >= in pick_anchors",
7979
# E6: classify_strengthening's `||` guard
8080
# (`old==Unparseable || new==Unparseable -> return None`) is equivalent
8181
# under `&&`. When exactly one side is Unparseable the `&&` mutant skips
8282
# the early return, but `classify_pair(Unparseable, _)` / `(_, Unparseable)`
8383
# has no matching arm and falls to `_ => None` ? identical observable
8484
# result for every input. The two-unparseable case is also caught earlier
8585
# by `if old == new { return None }`. No test can distinguish the mutant.
86-
"check_strengthening[.]rs:233(:[0-9]+)?: replace [|][|] with && in classify_strengthening",
86+
"check_strengthening[.]rs:[0-9]+:[0-9]+: replace [|][|] with && in classify_strengthening",
8787
# E7: the Rayon `*_par_*_threshold()` functions in parallel_config.rs
8888
# (vespertide-planner + vespertide-query) are perf-only dispatch knobs.
8989
# Replacing the returned threshold with 0 or 1 only changes WHEN the
@@ -97,51 +97,51 @@ exclude_re = [
9797
# ModifyColumnDefault for the same column), so they can never be equal.
9898
# `< -> <=` therefore has no reachable input that distinguishes it ?
9999
# equivalent. The `&&` operator on the same line remains in the gate.
100-
"ordering[.]rs:410(:[0-9]+)?: replace < with <= in sort_enum_default_dependencies",
100+
"ordering[.]rs:[0-9]+:[0-9]+: replace < with <= in sort_enum_default_dependencies",
101101
# E9: the `len() < *_par_*_threshold()` seq-vs-parallel DISPATCH comparisons.
102102
# Mutating `<` to ==/>/<= only changes which execution path is taken; the
103103
# sequential and Rayon paths produce identical results (covered by the
104104
# validate/diff/build result tests). Perf-only ? same category as E1.
105-
"validate/plan[.]rs:46(:[0-9]+)?: replace < with (==|>|<=) in find_plan_violations",
106-
"validate/plan[.]rs:167(:[0-9]+)?: replace < with (==|>|<=) in find_missing_fill_with",
107-
"validate/plan[.]rs:280(:[0-9]+)?: replace < with (==|>|<=) in find_missing_enum_fill_with",
108-
"validate/schema[.]rs:77(:[0-9]+)?: replace < with (==|>|<=) in find_schema_violations",
109-
"diff/mod[.]rs:49(:[0-9]+)?: replace < with (==|>|<=) in diff_schemas",
110-
"builder/mod[.]rs:63(:[0-9]+)?: replace < with (==|>|<=) in build_plan_queries",
105+
"validate/plan[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in find_plan_violations",
106+
"validate/plan[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in find_missing_fill_with",
107+
"validate/plan[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in find_missing_enum_fill_with",
108+
"validate/schema[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in find_schema_violations",
109+
"diff/mod[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in diff_schemas",
110+
"builder/mod[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in build_plan_queries",
111111
# E10: the pairwise contradiction loop `for j in (i + 1)..preds.len()`.
112112
# The `+ -> *` mutant yields `i * 1 == i`, so the inner loop additionally
113113
# visits the (i, i) self-pair `check_pair(col, p, p)`. A predicate never
114114
# contradicts itself (two identical Compare/In/Between/IsNull predicates
115115
# are always mutually satisfiable), so every added self-pair returns None
116116
# and the observable result is unchanged ? equivalent.
117-
"check_self_contradiction[.]rs:120(:[0-9]+)?: replace [+] with [*] in find_contradiction",
117+
"check_self_contradiction[.]rs:[0-9]+:[0-9]+: replace [+] with [*] in find_contradiction",
118118
# E11: is_definitely_mismatch's `(Json, _) => false` and
119119
# `(Custom { .. }, _) => false` arms return exactly the same value as the
120120
# match's `_ => false` catch-all. Deleting either arm makes that input
121121
# fall straight through to `_ => false` ? identical observable result,
122122
# equivalent.
123-
"check_type_mismatch[.]rs:366(:[0-9]+)?: delete match arm .* in is_definitely_mismatch",
124-
"check_type_mismatch[.]rs:395(:[0-9]+)?: delete match arm .* in is_definitely_mismatch",
123+
"check_type_mismatch[.]rs:[0-9]+:[0-9]+: delete match arm .* in is_definitely_mismatch",
124+
"check_type_mismatch[.]rs:[0-9]+:[0-9]+: delete match arm .* in is_definitely_mismatch",
125125
# E12: in find_primary_key_additions, `n_existing == 0 => NewColumns`.
126126
# The function acts ONLY on `ExistingColumns`; both NewColumns and the
127127
# `_ => Mixed` fallback hit `if !matches!(kind, ExistingColumns) continue;`.
128128
# Deleting the `0` arm sends n_existing==0 to Mixed (PK columns always
129129
# number >=1, so `0 == len` is unreachable) ? same `continue`, equivalent.
130-
"pk_additions[.]rs:115(:[0-9]+)?: delete match arm 0 in find_primary_key_additions",
130+
"pk_additions[.]rs:[0-9]+:[0-9]+: delete match arm 0 in find_primary_key_additions",
131131
# E13: in clear_index_fields, `filtered.len() < names.len()` gates whether
132132
# the multi-index array is rewritten after removing a constraint name. When
133133
# the name is absent, `filtered` is a clone of `names` (same elements, same
134134
# order), so the `<= ` branch would set `col.index = Some(Array(filtered))`
135135
# to a value byte-identical to the untouched original ? no observable
136136
# difference, equivalent.
137-
"constraint_ops[.]rs:148(:[0-9]+)?: replace < with <= in clear_index_fields",
137+
"constraint_ops[.]rs:[0-9]+:[0-9]+: replace < with <= in clear_index_fields",
138138
# E14: the loader's `paths.len() < LOAD_FILES_PAR_THRESHOLD` seq-vs-parallel
139139
# dispatch. Mutating `<` only changes whether files are loaded sequentially
140140
# or via Rayon; the loaded result is identical. Perf-only, same as E1/E9.
141-
"loader/src/migrations[.]rs:21(:[0-9]+)?: replace < with (==|>|<=) in load_migrations",
142-
"loader/src/migrations[.]rs:65(:[0-9]+)?: replace < with (==|>|<=) in load_migrations_from_dir",
143-
"loader/src/models[.]rs:43(:[0-9]+)?: replace < with (==|>|<=) in load_models_recursive",
144-
"loader/src/models[.]rs:145(:[0-9]+)?: replace < with (==|>|<=) in load_models_recursive_internal",
141+
"loader/src/migrations[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in load_migrations",
142+
"loader/src/migrations[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in load_migrations_from_dir",
143+
"loader/src/models[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in load_models_recursive",
144+
"loader/src/models[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in load_models_recursive_internal",
145145
# E15: pure `println!` display helpers (revision fill_with header/footer and
146146
# narrowing strategy descriptions). No return value or logic; replacing the
147147
# body with () or deleting a match arm only changes stdout decoration. Same
@@ -175,9 +175,58 @@ exclude_re = [
175175
# scanner's exponent loop condition. (Caught/missed mutants in these
176176
# functions stay in the gate; only the non-terminating ones are excluded.)
177177
"check_expr_parser[.]rs:[0-9]+:[0-9]+: replace [+]= with (-=|[*]=|/=) in tokenize_spanned",
178-
"check_expr_parser[.]rs:408(:[0-9]+)?: .* in tokenize_spanned",
178+
# The scanner's `while i < bytes.len() && ..` bounds guards. Relaxing the
179+
# bound is the same non-advancing class as the `+=` mutants above: the
180+
# cursor stops being the loop's decreasing measure and the scan never
181+
# terminates. Narrowed from a `.*`-in-tokenize_spanned wildcard so any
182+
# OTHER mutation in the scanner still has to be killed by a test.
183+
"check_expr_parser[.]rs:[0-9]+:[0-9]+: replace < with (<=|==|>) in tokenize_spanned",
179184
"check_expr_parser[.]rs:[0-9]+:[0-9]+: replace [+]= with (-=|[*]=|/=) in Parser::parse_predicate",
180185
"layout[.]rs:[0-9]+:[0-9]+: replace [+]= with (-=|[*]=|/=) in rebalance_groups",
186+
# Same non-termination class in the migration-filename byte scanner:
187+
# `render_migration_name` walks `i` (and the inner width cursor `j`) forward
188+
# by 1 or 2 per step. `*= 1` is the identity, and `-=` walks backwards into
189+
# an underflow, so either way the cursor stops being the loop's decreasing
190+
# measure and the scan never reaches `bytes.len()`. The scanner's comparison
191+
# and slice-bound mutants stay in the gate - `%012` and `%06v` cover those.
192+
"cli/src/utils[.]rs:[0-9]+:[0-9]+: replace [+]= with (-=|[*]=|/=) in render_migration_name",
193+
# E19: `String::with_capacity` / `Vec::reserve` sizing arithmetic. These
194+
# mutants change only how much the buffer pre-allocates; every one of these
195+
# functions then pushes the same bytes in the same order, so the returned
196+
# value is byte-identical and no assertion can distinguish them. (The
197+
# buffer-push helpers themselves stay in the gate - only the capacity
198+
# expression is excluded.)
199+
"naming/src/lib[.]rs:[0-9]+:[0-9]+: replace [+] with (-|[*]) in build_constraint_name",
200+
"schema/names[.]rs:[0-9]+:[0-9]+: replace ([+]|[*]) with ([*]|[+]) in join_column_names",
201+
"sql/helpers[.]rs:[0-9]+:[0-9]+: replace [+] with (-|[*]) in quote_ident_into",
202+
# E20: the loader's generic `paths.len() < LOAD_FILES_PAR_THRESHOLD`
203+
# seq-vs-parallel dispatch, extracted into `map_paths_with_threshold` by the
204+
# performance wave. Same perf-only category as E1/E7/E9/E14 - both arms map
205+
# the same closure over the same paths and collect the same result.
206+
"loader/src/parallel_config[.]rs:[0-9]+:[0-9]+: replace < with (==|>|<=) in map_paths_with_threshold",
207+
# E21: `sorted_column_refs` skips the sort for 0- or 1-element slices, which
208+
# are already sorted. Every mutant of that guard only changes WHETHER
209+
# `sort_unstable` runs on a slice too short to reorder, so the returned
210+
# order is identical either way.
211+
"diff/constraints[.]rs:[0-9]+:[0-9]+: replace > with (<|==|>=) in sorted_column_refs",
212+
# E22: `compute_integer_enum_remapping`'s empty-side fast path
213+
# (`from_items.is_empty() || to_items.is_empty()`). Under `&&` only the
214+
# both-empty case short-circuits, but the fall-through still yields an empty
215+
# map either way: an empty `from_items` iterates zero times, and an empty
216+
# `to_items` produces an empty `to_by_name` that matches no name. The guard
217+
# skips work, it does not change the result.
218+
"diff/columns[.]rs:[0-9]+:[0-9]+: replace [|][|] with && in compute_integer_enum_remapping",
219+
# E23: `build_create_table`'s `matches!(backend, MySql) || !has_unique_constraints`
220+
# picks between passing the constraint slice through by reference and
221+
# cloning a unique-free copy. `TableConstraint::Unique` dispatches to
222+
# `add_mysql_unique_constraint`, which no-ops on PG/SQLite, so both arms emit
223+
# the same CREATE TABLE - the guard only decides whether the clone is paid
224+
# for. (The `!` inside the partitioning filter on the next lines stays in the
225+
# gate: dropping it would keep only the uniques and lose the PK, which
226+
# `test_create_table_unique_alongside_primary_key` asserts against.) Anchored
227+
# on the COLUMN of the guard's `!` so the filter's `!` a few lines below is
228+
# not swept up - the two are indistinguishable by mutation text alone.
229+
"sql/create_table[.]rs:[0-9]+:77: delete ! in build_create_table",
181230
]
182231

183232
# Focus on logic-heavy crates. Exclude:
@@ -198,3 +247,4 @@ exclude_globs = [
198247

199248
# 3× baseline test time per mutant (handles proptest variance)
200249
timeout_multiplier = 3.0
250+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"changes":{"crates/vespertide-config/Cargo.toml":"Minor","crates/vespertide-core/Cargo.toml":"Minor","crates/vespertide-exporter/Cargo.toml":"Minor","crates/vespertide-planner/Cargo.toml":"Minor","crates/vespertide-query/Cargo.toml":"Minor"},"note":"성능 최적화 웨이브: 미사용 public API 정리(NameCase::is_*, EnumValues::variant_names/to_sql_values, sql::helpers 일부, find_primary_key_removals 시그니처)와 Orm::Prisma 변형 추가로 0.x 기준 breaking","date":"2026-08-20T03:03:26.0689134Z"}

‎.github/workflows/CI.yml‎

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
name: fmt
3434
runs-on: ubuntu-latest
3535
steps:
36-
- uses: actions/checkout@v6
36+
- uses: actions/checkout@v7
3737
- uses: actions-rust-lang/setup-rust-toolchain@v1
3838
with:
3939
components: rustfmt
@@ -44,7 +44,7 @@ jobs:
4444
name: clippy
4545
runs-on: ubuntu-latest
4646
steps:
47-
- uses: actions/checkout@v6
47+
- uses: actions/checkout@v7
4848
- uses: actions-rust-lang/setup-rust-toolchain@v1
4949
with:
5050
components: clippy
@@ -55,7 +55,7 @@ jobs:
5555
name: test
5656
runs-on: ubuntu-latest
5757
steps:
58-
- uses: actions/checkout@v6
58+
- uses: actions/checkout@v7
5959
- uses: actions-rust-lang/setup-rust-toolchain@v1
6060
- name: Test
6161
run: cargo test --workspace --all-features
@@ -73,7 +73,7 @@ jobs:
7373
matrix:
7474
threads: ["1", "4"]
7575
steps:
76-
- uses: actions/checkout@v6
76+
- uses: actions/checkout@v7
7777
- uses: actions-rust-lang/setup-rust-toolchain@v1
7878
- name: Test with Rayon thread count
7979
run: cargo test --workspace --all-features --exclude vespertide-fuzz
@@ -89,7 +89,7 @@ jobs:
8989
name: SQL validity (daemon-free)
9090
runs-on: ubuntu-latest
9191
steps:
92-
- uses: actions/checkout@v6
92+
- uses: actions/checkout@v7
9393
- uses: actions-rust-lang/setup-rust-toolchain@v1
9494
- name: Install build-essential for pg_query (PG C parser)
9595
run: sudo apt-get update && sudo apt-get install -y build-essential libreadline-dev zlib1g-dev flex bison
@@ -105,7 +105,7 @@ jobs:
105105
name: cargo-deny
106106
runs-on: ubuntu-latest
107107
steps:
108-
- uses: actions/checkout@v6
108+
- uses: actions/checkout@v7
109109
- uses: actions-rust-lang/setup-rust-toolchain@v1
110110
- uses: EmbarkStudios/cargo-deny-action@v2
111111
with:
@@ -116,7 +116,7 @@ jobs:
116116
runs-on: ubuntu-latest
117117
if: github.event_name == 'pull_request'
118118
steps:
119-
- uses: actions/checkout@v6
119+
- uses: actions/checkout@v7
120120
with:
121121
fetch-depth: 0
122122
- uses: actions-rust-lang/setup-rust-toolchain@v1
@@ -196,7 +196,7 @@ jobs:
196196
changepacks: ${{ steps.changepacks.outputs.changepacks }}
197197
release_assets_urls: ${{ steps.changepacks.outputs.release_assets_urls }}
198198
steps:
199-
- uses: actions/checkout@v6
199+
- uses: actions/checkout@v7
200200
# changepacks/action@main: project-internal action intentionally tracks main.
201201
# `publish: true` runs `cargo publish` for every Cargo.toml changed in this
202202
# release wave. `release_assets_urls` output is consumed by the downstream
@@ -258,15 +258,15 @@ jobs:
258258
archive: zip
259259
use_cross: false
260260
steps:
261-
- uses: actions/checkout@v6
261+
- uses: actions/checkout@v7
262262

263263
- uses: actions-rust-lang/setup-rust-toolchain@v1
264264
with:
265265
target: ${{ matrix.target }}
266266

267267
- name: Install cross (aarch64-unknown-linux-gnu only)
268268
if: matrix.use_cross
269-
uses: taiki-e/install-action@v2.81.6
269+
uses: taiki-e/install-action@v2.86.3
270270
with:
271271
tool: cross
272272

@@ -354,7 +354,7 @@ jobs:
354354
binary_dir_name: win32-x64
355355
archive_format: zip
356356
steps:
357-
- uses: actions/checkout@v6
357+
- uses: actions/checkout@v7
358358

359359
- uses: oven-sh/setup-bun@v2
360360
with:
@@ -485,7 +485,7 @@ jobs:
485485
permissions:
486486
contents: write
487487
steps:
488-
- uses: actions/checkout@v6
488+
- uses: actions/checkout@v7
489489
with:
490490
fetch-depth: 0
491491

@@ -548,7 +548,7 @@ jobs:
548548
name: doc
549549
runs-on: ubuntu-latest
550550
steps:
551-
- uses: actions/checkout@v6
551+
- uses: actions/checkout@v7
552552
- uses: actions-rust-lang/setup-rust-toolchain@v1
553553
- name: Check docs
554554
run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --workspace
@@ -557,7 +557,7 @@ jobs:
557557
name: schema-drift
558558
runs-on: ubuntu-latest
559559
steps:
560-
- uses: actions/checkout@v6
560+
- uses: actions/checkout@v7
561561
- uses: actions-rust-lang/setup-rust-toolchain@v1
562562
- name: Regenerate schemas
563563
run: cargo run -p vespertide-schema-gen -- --out _tmp_schemas
@@ -568,7 +568,7 @@ jobs:
568568
name: insta-pending
569569
runs-on: ubuntu-latest
570570
steps:
571-
- uses: actions/checkout@v6
571+
- uses: actions/checkout@v7
572572
- uses: actions-rust-lang/setup-rust-toolchain@v1
573573
- name: Run exporter snapshots
574574
run: cargo test -p vespertide-exporter
@@ -584,7 +584,7 @@ jobs:
584584
name: line-budget
585585
runs-on: ubuntu-latest
586586
steps:
587-
- uses: actions/checkout@v6
587+
- uses: actions/checkout@v7
588588
- name: Check Rust line budget
589589
run: sh scripts/check-line-budget.sh
590590

@@ -595,7 +595,7 @@ jobs:
595595
image: xd009642/tarpaulin:develop-nightly
596596
options: --security-opt seccomp=unconfined
597597
steps:
598-
- uses: actions/checkout@v6
598+
- uses: actions/checkout@v7
599599
- uses: oven-sh/setup-bun@v2
600600
with:
601601
bun-version: latest

‎.github/workflows/bench.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
runs-on: ubuntu-latest
3333
timeout-minutes: 30
3434
steps:
35-
- uses: actions/checkout@v6
35+
- uses: actions/checkout@v7
3636

3737
- uses: actions-rust-lang/setup-rust-toolchain@v1
3838

@@ -54,7 +54,7 @@ jobs:
5454
runs-on: ubuntu-latest
5555
timeout-minutes: 15
5656
steps:
57-
- uses: actions/checkout@v6
57+
- uses: actions/checkout@v7
5858

5959
- uses: actions-rust-lang/setup-rust-toolchain@v1
6060

‎.github/workflows/deploy-pages.yml‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,26 @@ jobs:
2323
runs-on: ubuntu-latest
2424
steps:
2525
- name: Checkout
26-
uses: actions/checkout@v6
26+
uses: actions/checkout@v7
2727

2828
- name: Install bun
2929
uses: oven-sh/setup-bun@v2
3030

3131
- name: Cache bun dependencies
32-
uses: actions/cache@v5
32+
uses: actions/cache@v6
3333
with:
3434
path: ~/.bun/install/cache
3535
key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }}
3636
restore-keys: |
3737
bun-${{ runner.os }}-
3838
3939
- name: Install Node.js
40-
uses: actions/setup-node@v6
40+
uses: actions/setup-node@v7
4141
with:
4242
node-version: 22
4343

4444
- name: Cache Next.js build
45-
uses: actions/cache@v5
45+
uses: actions/cache@v6
4646
with:
4747
path: |
4848
apps/landing/.next/cache

‎.github/workflows/fuzz.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
- fuzz_migration_apply
4141
- fuzz_lsp_request
4242
steps:
43-
- uses: actions/checkout@v6
43+
- uses: actions/checkout@v7
4444

4545
- uses: actions-rust-lang/setup-rust-toolchain@v1
4646
with:
@@ -51,12 +51,12 @@ jobs:
5151
# crt-static libc is incompatible with `-Zsanitizer=address`.
5252
target: x86_64-unknown-linux-gnu
5353

54-
- uses: taiki-e/install-action@v2.81.6
54+
- uses: taiki-e/install-action@v2.86.3
5555
with:
5656
tool: cargo-fuzz
5757

5858
- name: Cache corpus
59-
uses: actions/cache@v5
59+
uses: actions/cache@v6
6060
with:
6161
path: fuzz/corpus/${{ matrix.target }}
6262
key: fuzz-corpus-${{ matrix.target }}-${{ github.sha }}

‎.github/workflows/mutants.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ jobs:
2727
shard:
2828
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
2929
steps:
30-
- uses: actions/checkout@v6
30+
- uses: actions/checkout@v7
3131
with:
3232
fetch-depth: 0
3333

3434
- uses: actions-rust-lang/setup-rust-toolchain@v1
3535

36-
- uses: taiki-e/install-action@v2.81.6
36+
- uses: taiki-e/install-action@v2.86.3
3737
with:
3838
tool: cargo-mutants
3939

0 commit comments

Comments
 (0)