From d1db522bfcec52a432347afa31de1fee12a42852 Mon Sep 17 00:00:00 2001 From: Charliechen114514 <725610365@qq.com> Date: Sun, 7 Jun 2026 09:14:11 +0800 Subject: [PATCH 1/4] chore: update the build cache logic for cache friendly build, for a pr safety build check --- scripts/build.ts | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/scripts/build.ts b/scripts/build.ts index 3815f6f2e..6267057b6 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -94,7 +94,7 @@ function countMdFiles(dir: string): number { return count } -/** Compute a fast hash of a directory's file mtimes + sizes for change detection */ +/** Compute a stable content hash for change detection across fresh checkouts. */ function hashDir(dir: string): string { const h = createHash('sha256') function walk(d: string) { @@ -104,8 +104,9 @@ function hashDir(dir: string): string { if (e.name.startsWith('.')) continue const full = join(d, e.name) if (e.isDirectory()) { walk(full); continue } - const s = statSync(full) - h.update(`${relative(dir, full)}:${s.size}:${s.mtimeMs}\n`) + h.update(`file:${relative(dir, full)}\n`) + h.update(readFileSync(full)) + h.update('\n') } } catch { /* ignore */ } } @@ -113,6 +114,26 @@ function hashDir(dir: string): string { return h.digest('hex').substring(0, 16) } +function hashFile(path: string): string { + const h = createHash('sha256') + if (!existsSync(path)) return '' + h.update(readFileSync(path)) + return h.digest('hex').substring(0, 16) +} + +function hashBuildInputs(): string { + const h = createHash('sha256') + for (const [label, value] of [ + ['site', hashDir(MAIN_VP)], + ['package', hashFile(join(PROJECT_ROOT, 'package.json'))], + ['lockfile', hashFile(join(PROJECT_ROOT, 'pnpm-lock.yaml'))], + ['build-script', hashFile(join(PROJECT_ROOT, 'scripts', 'build.ts'))], + ]) { + h.update(`${label}:${value}\n`) + } + return h.digest('hex').substring(0, 16) +} + // ── Manifest (incremental build state) ────────────────────── interface ManifestEntry { hash: string; timestamp: string } @@ -232,10 +253,11 @@ interface SearchIndexSource { lang: 'zh' | 'en' | 'mixed' } -function prepareVolume(vol: Volume, lang: 'zh' | 'en', manifest: Manifest): BuildTask { +function prepareVolume(vol: Volume, lang: 'zh' | 'en', manifest: Manifest, buildInputsHash: string): BuildTask { const volDocDir = lang === 'en' ? join(DOCUMENTS, 'en', vol.srcDir) : join(DOCUMENTS, vol.srcDir) const id = lang === 'en' ? `${vol.name}-en` : vol.name - const cacheKey = existsSync(volDocDir) ? hashDir(volDocDir) : '' + const docHash = existsSync(volDocDir) ? hashDir(volDocDir) : '' + const cacheKey = `${buildInputsHash}-${docHash}` const prev = manifest[id] const cached = !FORCE_REBUILD && prev && prev.hash === cacheKey && existsSync(join(CACHE_DIR, 'output', id)) return { id, vol, lang, cacheKey, cached } @@ -585,6 +607,7 @@ async function main() { mkdirSync(join(BUILD_TMP, 'output'), { recursive: true }) const manifest = readManifest() + const buildInputsHash = hashBuildInputs() // ── Step 1: Build root ────────────────────────────────── logStep('Step 1/4: Building root site (index, tags)') @@ -629,7 +652,7 @@ async function main() { for (const lang of ['zh', 'en'] as const) { const volDocDir = lang === 'en' ? join(DOCUMENTS, 'en', vol.srcDir) : join(DOCUMENTS, vol.srcDir) if (!existsSync(volDocDir)) continue - tasks.push(prepareVolume(vol, lang, manifest)) + tasks.push(prepareVolume(vol, lang, manifest, buildInputsHash)) } } From ce4d6298456fe4a078fdbd973a13438ee9df7263 Mon Sep 17 00:00:00 2001 From: Charliechen114514 <725610365@qq.com> Date: Sun, 7 Jun 2026 09:25:41 +0800 Subject: [PATCH 2/4] chore: update the build cache logic for cache friendly build, for a pr safety build check --- .github/workflows/build-check.yml | 6 ++++-- .github/workflows/deploy.yml | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-check.yml b/.github/workflows/build-check.yml index cd3969d33..e9fdfe4a6 100644 --- a/.github/workflows/build-check.yml +++ b/.github/workflows/build-check.yml @@ -31,8 +31,10 @@ jobs: uses: actions/cache@v4 with: path: site/.vitepress/.build-cache - key: vitepress-build-${{ hashFiles('documents/**') }} - restore-keys: vitepress-build- + key: vitepress-build-${{ runner.os }}-${{ hashFiles('documents/**', 'site/.vitepress/config/**', 'site/.vitepress/plugins/**', 'site/.vitepress/public/**', 'site/.vitepress/theme/**', 'scripts/build.ts', 'package.json', 'pnpm-lock.yaml') }} + restore-keys: | + vitepress-build-${{ runner.os }}- + vitepress-build- - name: Build run: pnpm build diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 031910fc8..62e0bea67 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -36,8 +36,10 @@ jobs: uses: actions/cache@v4 with: path: site/.vitepress/.build-cache - key: vitepress-build-${{ hashFiles('documents/**') }} - restore-keys: vitepress-build- + key: vitepress-build-${{ runner.os }}-${{ hashFiles('documents/**', 'site/.vitepress/config/**', 'site/.vitepress/plugins/**', 'site/.vitepress/public/**', 'site/.vitepress/theme/**', 'scripts/build.ts', 'package.json', 'pnpm-lock.yaml') }} + restore-keys: | + vitepress-build-${{ runner.os }}- + vitepress-build- - name: Build run: pnpm build From 60acd055865637975363b2d69f3d1b7252df11ac Mon Sep 17 00:00:00 2001 From: Charliechen114514 <725610365@qq.com> Date: Sun, 7 Jun 2026 09:46:02 +0800 Subject: [PATCH 3/4] update: add references at vairant staff --- documents/vol2-modern-features/ch04-type-safety/03-variant.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/documents/vol2-modern-features/ch04-type-safety/03-variant.md b/documents/vol2-modern-features/ch04-type-safety/03-variant.md index 8919ec24f..b9ad26975 100644 --- a/documents/vol2-modern-features/ch04-type-safety/03-variant.md +++ b/documents/vol2-modern-features/ch04-type-safety/03-variant.md @@ -437,6 +437,10 @@ std::cout << "sizeof(string): " << sizeof(std::string) << "\n"; // 典型输出:32 ``` +> 这里稍作补充,int 的大小如何,可以在如下的网址上阅读,简单的说,int 被规定为至少16 bits,也就是2字节大小,其他平台一律4字节。当然这个事情别当八股文背诵。 +> 可以参考 [YukunJ](https://github.com/YukunJ) 老师提供的[案例](https://godbolt.org/z/sbvEMW56G) + + 这个大小对于大多数应用来说完全可接受。但在内存极端受限的嵌入式场景中,你可能需要评估一下是否值得用 `variant` 替代手写的 `union` + `enum` 标签方案。`variant` 带来的类型安全收益通常远大于几个字节的内存开销。 ## 小结 From 403a59a95439662f03e38c9ae2f071ed569cc32c Mon Sep 17 00:00:00 2001 From: Charliechen114514 <725610365@qq.com> Date: Sun, 7 Jun 2026 09:52:23 +0800 Subject: [PATCH 4/4] update: add reference for types --- documents/vol2-modern-features/ch04-type-safety/03-variant.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/documents/vol2-modern-features/ch04-type-safety/03-variant.md b/documents/vol2-modern-features/ch04-type-safety/03-variant.md index b9ad26975..72741354f 100644 --- a/documents/vol2-modern-features/ch04-type-safety/03-variant.md +++ b/documents/vol2-modern-features/ch04-type-safety/03-variant.md @@ -437,10 +437,9 @@ std::cout << "sizeof(string): " << sizeof(std::string) << "\n"; // 典型输出:32 ``` -> 这里稍作补充,int 的大小如何,可以在如下的网址上阅读,简单的说,int 被规定为至少16 bits,也就是2字节大小,其他平台一律4字节。当然这个事情别当八股文背诵。 +> 这里稍作补充,int 的大小如何,可以在这个[网址](https://en.cppreference.com/cpp/language/types)上阅读,简单的说,int 被规定为至少16 bits,也就是2字节大小,其他平台一律4字节。当然这个事情别当八股文背诵。 > 可以参考 [YukunJ](https://github.com/YukunJ) 老师提供的[案例](https://godbolt.org/z/sbvEMW56G) - 这个大小对于大多数应用来说完全可接受。但在内存极端受限的嵌入式场景中,你可能需要评估一下是否值得用 `variant` 替代手写的 `union` + `enum` 标签方案。`variant` 带来的类型安全收益通常远大于几个字节的内存开销。 ## 小结