LC-Finder 0.2.0 Beta 开发日志

发表于2018年10月15日

2018-10-24

对文件列表的渲染流程做了一些调整,采用类似于生产者消费者的工作模式,大致如下:

  1. 文件扫描线程在每扫描完一批文件后,将它们追加到线程安全的暂存区中
  2. 取消视图同步线程,改用定时器来实现文件列表渲染,每隔 200 毫秒从暂存区取出全部文件数据,然后追加到视图中

所有 UI 操作都在主线程上进行,可以避免因资源不同步而导致的内存访问越界的问题。

接下来是调整缩略图视图组件,在加载缩略图时清空内容很容易出错,需要把一些操作移动到主线程上。

2018-10-20

用 Dr.Memory 检测内存泄漏问题时,会输出一些来自 UnQLite 的错误,例如:

~~Dr.M~~ Error #4: UNINITIALIZED READ: reading register eax
~~Dr.M~~ # 0 unqlite.dll!SyRandomness          [c:\users\lc\documents\github\unqlite\unqlite.c:30381]
~~Dr.M~~ # 1 unqlite.dll!unqlitePagerOpen      [c:\users\lc\documents\github\unqlite\unqlite.c:57810]
~~Dr.M~~ # 2 unqlite.dll!unqliteInitDatabase   [c:\users\lc\documents\github\unqlite\unqlite.c:4120]
~~Dr.M~~ # 3 unqlite.dll!unqlite_open          [c:\users\lc\documents\github\unqlite\unqlite.c:4342]
~~Dr.M~~ # 4 KERNEL32.dll!BaseThreadInitThunk +0x23     (0x76928484 <KERNEL32.dll+0x18484>)
~~Dr.M~~ Note: @0:00:11.229 in thread 29492
~~Dr.M~~ Note: instruction: movzx  0x02(%eax,%ecx) -> %eax
~~Dr.M~~
~~Dr.M~~ Error #5: UNINITIALIZED READ: reading register eax
~~Dr.M~~ # 0 unqlite.dll!SyRandomness          [c:\users\lc\documents\github\unqlite\unqlite.c:30381]
~~Dr.M~~ # 1 unqlite.dll!unqlitePagerOpen      [c:\users\lc\documents\github\unqlite\unqlite.c:57810]
~~Dr.M~~ # 2 unqlite.dll!unqliteInitDatabase   [c:\users\lc\documents\github\unqlite\unqlite.c:4120]
~~Dr.M~~ # 3 unqlite.dll!unqlite_open          [c:\users\lc\documents\github\unqlite\unqlite.c:4342]
~~Dr.M~~ # 4 KERNEL32.dll!BaseThreadInitThunk +0x23     (0x76928484 <KERNEL32.dll+0x18484>)
~~Dr.M~~ Note: @0:00:11.235 in thread 29492
~~Dr.M~~ Note: instruction: mov    %bl -> 0x02(%eax,%ecx)

这堆内容很碍眼,我只想关注自己程序的问题,于是就看了下它的文档,据说可以用 -suppress 参数指定一个文件,只需在这个文件里写上需要屏蔽的错误即可,内容格式可以参考它的安装目录里的 suppress-default.txt 文件。

2018-10-15

LevelDB 的数据库文件不是单个文件,获取占用空间和移除文件不能用 stat() 和 remove() 来实现。LevelDB 有提供 leveldb_approximate_sizes() 函数来获取大致的大小,但在看了他的文档和示例代码后,还是不知道这函数的参数是什么意思,start 和 limit 里的 a z 表示什么?

  StartPhase("approximate_sizes");
  {
    int i;
    int n = 20000;
    char keybuf[100];
    char valbuf[100];
    uint64_t sizes[2];
    const char* start[2] = { "a", "k00000000000000010000" };
    size_t start_len[2] = { 1, 21 };
    const char* limit[2] = { "k00000000000000010000", "z" };
    size_t limit_len[2] = { 21, 1 };
    leveldb_writeoptions_set_sync(woptions, 0);
    for (i = 0; i < n; i++) {
      snprintf(keybuf, sizeof(keybuf), "k%020d", i);
      snprintf(valbuf, sizeof(valbuf), "v%020d", i);
      leveldb_put(db, woptions, keybuf, strlen(keybuf), valbuf, strlen(valbuf),
                  &err);
      CheckNoError(err);
    }
    leveldb_approximate_sizes(db, 2, start, start_len, limit, limit_len, sizes);
    CheckCondition(sizes[0] > 0);
    CheckCondition(sizes[1] > 0);
  }

就算不用 leveldb_approximate_sizes() 也可以自己手动遍历文件累加大小,至于移除数据库,可以用 leveldb_destroy_db()。

leveldb 产生的 ldb 文件太多,大小都是 401KB,一个文件装不了多少张的缩略图,需要调整数据文件大小。他的头文件里有给出 leveldb_options_set_max_file_size(),但 vcpkg 提供的是 bitcoin-core 的 leveldb,没有这个函数,算了,懒得自己编译 google 的 leveldb,文件数太多也不算大问题。

对此文章有疑问?你可以点击此链接反馈你的问题