d为何读写不一致

import std.stdio;
import core.sync.rwmutex : ReadWriteMutex;

enum PAGE_SIZE = 4096;
alias PageId = uint;

ubyte[] toBytes(uint value)
{
    ubyte[] bytes = new ubyte[4];
    bytes[0] = cast(ubyte)(value >> 24);
    bytes[1] = cast(ubyte)(value >> 16);
    bytes[2] = cast(ubyte)(value >> 8);
    bytes[3] = cast(ubyte)(value);
    return bytes;
}

class DiskManager
{
    File dbFile;
    __gshared ReadWriteMutex dbIOMutex;

    shared static this()
    {
        this.dbIOMutex = new ReadWriteMutex(ReadWriteMutex.Policy.PREFER_WRITERS);
    }

    this(string dbFileName)
    {
        this.dbFile = File(dbFileName, "ab+");
    }

    void removeIfExists()
    {
        static import std.file;

        if (std.file.exists(dbFile.name))
        {
            std.file.remove(dbFile.name);
        }
    }

    void readPage(PageId pageId, out ubyte[PAGE_SIZE] pageData)
    {
        synchronized (dbIOMutex.reader)
        {
            dbFile.seek(pageId * PAGE_SIZE);
            dbFile.rawRead(pageData);
        }
    }

    void writePage(PageId pageId, ubyte[PAGE_SIZE] pageData)
    {
        synchronized (dbIOMutex.writer)
        {
            dbFile.seek(pageId * PAGE_SIZE);
            dbFile.rawWrite(pageData);
        }
    }
}

void singleReadWrite()
{
     // Scenario: 写并读回
    DiskManager diskManager = new DiskManager("test.db");
    diskManager.removeIfExists();

    PageId pageId = 0;

    ubyte[PAGE_SIZE] pageData = new ubyte[PAGE_SIZE];
    pageData[0..4] = [1,2,3,4];
    diskManager.writePage(pageId, pageData);

    ubyte[PAGE_SIZE] readData = new ubyte[PAGE_SIZE];
    diskManager.readPage(pageId, readData);

    writeln("pageData[0..4] = ", pageData[0 .. 4]);
    writeln("readData[0..4] = ", readData[0 .. 4]);

    assert(pageData[0..4] == readData[0..4]);
}

void multiReadWrite()
{
    // 场景: 成功读写相同位置
    DiskManager diskManager = new DiskManager("test.db");
    diskManager.removeIfExists();

    PageId pageId = 0;

    foreach (i; 0 .. 10)
    {
        ubyte[PAGE_SIZE] pageData = new ubyte[PAGE_SIZE];

        pageData[0 .. 4] = toBytes(i);
        diskManager.writePage(pageId, pageData);

        ubyte[PAGE_SIZE] readData = new ubyte[PAGE_SIZE];
        diskManager.readPage(pageId, readData);

        writeln("pageData[0..4] = ", pageData[0 .. 4]);
        writeln("readData[0..4] = ", readData[0 .. 4]);

        assert(pageData[0] == readData[0]);
        assert(pageData[1] == readData[1]);
        assert(pageData[2] == readData[2]);
    }
}

void main()
{

    singleReadWrite();
    writeln("~~~~~~");
    multiReadWrite();
}

单次读写正常:

pageData[0..4] = [1, 2, 3, 4]
readData[0..4] = [1, 2, 3, 4]

放在for循环,就出错了:

pageData[0..4] = [0, 0, 0, 0]
readData[0..4] = [0, 0, 0, 0]

pageData[0..4] = [0, 0, 0, 1]
readData[0..4] = [0, 0, 0, 0]

pageData[0..4] = [0, 0, 0, 2]
readData[0..4] = [0, 0, 0, 0]

pageData[0..4] = [0, 0, 0, 3]
readData[0..4] = [0, 0, 0, 0]

pageData[0..4] = [0, 0, 0, 4]
readData[0..4] = [0, 0, 0, 0]

// ...

可能,需要刷新.

void writePage(PageId pageId, ubyte[PAGE_SIZE] pageData)
{
    synchronized (dbIOMutex.writer)
    {
        dbFile.seek(pageId * PAGE_SIZE);
        dbFile.rawWrite(pageData);
        dbFile.flush();//加了这句.
        dbFile.sync();
    }
}

仍然有问题.
问题出在模式上.

exists(dbFileName) ? "r+" : "w+"

这样,就可修复了.应重新实现FILE*描述符.

posted @   zjh6  阅读(11)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示