15 / 24 · 實作
實作:檢查 1024 種停頓樣式
以所有十週期 ready 樣式測試保持、替換與清空。
單元可免費閱讀,註冊課程即可儲存學習進度。
停頓下保留數值與順序
手動建立 elastic-model.mjs,儲存下列程式,並執行 node elastic-model.mjs。來源端提供四個有序項目,只在接受時前進。樣式位元零控制邊緣 0,位元一控制邊緣 1,依此類推。窮舉全部 1024 個十位元 ready 樣式,再讓接收端持續 ready,排空尚未完成的工作。
先由舊槽交付,再決定替換。空槽即使接收端停頓也可接受一項。已滿且停頓的槽,不能讓來源端前進。若每個邊緣都遞增 next,便會捨棄未被接受的項目;即使緩衝器正確,測試來源端也會錯誤。
import assert from 'node:assert/strict';
const values = [0, 9, 255, 12];
let deliveries = 0;
for (let pattern = 0; pattern < 1024; pattern++) {
let slot = null, next = 0;
const seen = [];
for (let edge = 0; edge < 20; edge++) {
const ready = edge >= 10 || ((pattern >>> edge) & 1) === 1;
const old = slot;
const inReady = old === null || ready;
if (old !== null && ready) seen.push(old);
if (inReady) {
slot = next < values.length ? { tag: next, y: values[next] } : null;
if (slot !== null) next++;
} else {
assert.deepEqual(slot, old);
}
assert.equal(next - seen.length, Number(slot !== null));
}
assert.deepEqual(seen, values.map((y, tag) => ({ tag, y })));
assert.equal(slot, null);
deliveries += seen.length;
}
console.log(`ELASTIC PASS: 1024 patterns, ${deliveries} deliveries`);樣式零讓接收端在前十個邊緣停頓。Tag0,y0 在邊緣 0 進入空槽,一直保持到邊緣 9。邊緣 10 交付它並儲存 tag1,y9。標籤 1、2、3 接著在邊緣 11、12、13 傳輸。有效的零不能誤認為 null。成功會回報 1024 種樣式與 4096 次交付。
每個邊緣後,接受數減去交付數都等於當前占用量。此局部計數能比最終輸出比較更早縮小錯誤範圍。保持檢查涵蓋負載保留,但比較實際實作時,必須觀察其真正輸出,而非僅觀察模型未改變的變數。窮舉十週期樣式是有限測試,不是所有可能停頓長度的證明。最終完成還假設接收端最後會 ready;無限期背壓要求保留,不保證交付。
自己試試看
樣式零時,來源端 next 在邊緣 0 到 9 前進多少?邊緣 10 之後,占用量與 next-seen.length 各是多少?
查看解說
只有邊緣 0 的項目被接受,因此 next=1。邊緣 10,tag0 傳輸且 tag1 進入:next=2、seen.length=1,兩者差與槽占用量都為一。
✓ 已學習