Altifigence Academy

15 / 24 · 實作

實作:檢查 1024 種停頓樣式

以所有十週期 ready 樣式測試保持、替換與清空。

停頓下保留數值與順序

手動建立 elastic-model.mjs,儲存下列程式,並執行 node elastic-model.mjs。來源端提供四個有序項目,只在接受時前進。樣式位元零控制邊緣 0,位元一控制邊緣 1,依此類推。窮舉全部 1024 個十位元 ready 樣式,再讓接收端持續 ready,排空尚未完成的工作。

先由舊槽交付,再決定替換。空槽即使接收端停頓也可接受一項。已滿且停頓的槽,不能讓來源端前進。若每個邊緣都遞增 next,便會捨棄未被接受的項目;即使緩衝器正確,測試來源端也會錯誤。

javascript
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,兩者差與槽占用量都為一。

Lesson files

elastic-model.mjs ↓

此選擇適用於本瀏覽器,隨時可從頁尾變更。