Round-seven fixes: swap name room for .tmp; input and notice details
- The shortened fallback swap name was capped at exactly NAME_MAX, so compaction's '<journal>.tmp' failed with ENAMETOOLONG on every checkpoint and the journal grew by a full copy of the buffer each time. Cap it at NAME_MAX - 4. - A lone UTF-8 lead byte (8-bit Meta terminals) waited a second for continuation bytes on every key; wait 250 ms. An invalid byte now ends a pending ESC/C-k prefix instead of leaving it for the next key. - Journal notices are shown after a deferred open's own status (which used to overwrite them), all pending ones at once, and the lock-out notice is not repeated after every save while the lock is still held. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
This commit is contained in:
@@ -1471,6 +1471,12 @@ TEST(Audit_Swap_FailuresReachTheUser)
|
||||
sb.Flush(&b);
|
||||
ASSERT_TRUE(sb.TakeUserNotice().find("another kte") != std::string::npos);
|
||||
ASSERT_EQ(sb.TakeUserNotice(), std::string());
|
||||
// Saving resets the journal and retries the lock; still held by A, but
|
||||
// the user was already told.
|
||||
sb.ResetJournal(b);
|
||||
b.insert_text(0, 0, "b");
|
||||
sb.Flush(&b);
|
||||
ASSERT_EQ(sb.TakeUserNotice(), std::string());
|
||||
b.SetSwapRecorder(nullptr);
|
||||
sb.Detach(&b, false);
|
||||
a.SetSwapRecorder(nullptr);
|
||||
@@ -1503,17 +1509,25 @@ TEST(Audit_Swap_LongBasenameStillJournaled)
|
||||
const std::string path = (d.path / (std::string(240, 'n') + ".txt")).string();
|
||||
std::ofstream(path) << "base\n";
|
||||
const std::string swp = kte::SwapManager::ComputeSwapPathForFilename(path);
|
||||
ASSERT_TRUE(std::filesystem::path(swp).filename().string().size() <= 255);
|
||||
// Room for compaction's "<journal>.tmp" too.
|
||||
ASSERT_TRUE(std::filesystem::path(swp).filename().string().size() + 4 <= 255);
|
||||
std::filesystem::remove(swp);
|
||||
Buffer a;
|
||||
std::string err;
|
||||
ASSERT_TRUE(a.OpenFromFile(path, err));
|
||||
kte::SwapManager sm;
|
||||
kte::SwapConfig cfg;
|
||||
cfg.checkpoint_bytes = 100;
|
||||
cfg.compact_bytes = 1000;
|
||||
sm.SetConfig(cfg);
|
||||
sm.Attach(&a);
|
||||
a.SetSwapRecorder(sm.RecorderFor(&a));
|
||||
a.insert_text(0, 0, "X");
|
||||
for (int i = 0; i < 50; ++i)
|
||||
a.insert_text(0, 0, std::string(200, 'X'));
|
||||
sm.Flush(&a);
|
||||
ASSERT_TRUE(std::filesystem::exists(swp));
|
||||
// Compaction works: the journal holds about one checkpoint, not fifty.
|
||||
ASSERT_TRUE(std::filesystem::file_size(swp) < 40000);
|
||||
a.SetSwapRecorder(nullptr);
|
||||
sm.Detach(&a, true);
|
||||
ASSERT_TRUE(!std::filesystem::exists(swp));
|
||||
|
||||
Reference in New Issue
Block a user