当前位置: 首页 > 工具软件 > chromium-net > 使用案例 >

Chromium内核net模块disk cache/index file的文件存储机制

笪智志
2023-12-01

http://localhost:8080/source/xref/greentea-7.2/net/disk_cache/simple/simple_index_file.cc (M43版本)

// static

// static
void SimpleIndexFile::Deserialize(const char* data, int data_len,
                                  base::Time* out_cache_last_modified,
                                  SimpleIndexLoadResult* out_result) {
  DCHECK(data);

  out_result->Reset();
  SimpleIndex::EntrySet* entries = &out_result->entries;

  Pickle pickle(data, data_len);
  if (!pickle.data()) {
    LOG(WARNING) << "Corrupt Simple Index File.";
    return;
  }

  PickleIterator pickle_it(pickle);
  SimpleIndexFile::PickleHeader* header_p =
      pickle.headerT<SimpleIndexFile::PickleHeader>();
  const uint32 crc_read = header_p->crc;
  const uint32 crc_calculated = CalculatePickleCRC(pickle);

  if (crc_read != crc_calculated) {
    LOG(WARNING) << "Invalid CRC in Simple Index file.";
    return;
  }

  SimpleIndexFile::IndexMetadata index_metadata;
  if (!index_metadata.Deserialize(&pickle_it)) {
    LOG(ERROR) << "Invalid index_metadata on Simple Cache Index.";
    return;
  }

  if (!index_metadata.CheckIndexMetadata()) {
    LOG(ERROR) << "Invalid index_metadata on Simple Cache Index.";
    return;
  }

#if !defined(OS_WIN)
  // TODO(gavinp): Consider using std::unordered_map.
  entries->resize(index_metadata.GetNumberOfEntries() + kExtraSizeForMerge);
#endif
index实际上是一个类似于hashmap的数据结构。不幸的是,从这里的反序列化代码来看,其实hashmap的加载并不涉及每个entry的随机load。实际上是顺序load all并就地构造新的hashmap对象。

但是,如果一开始就创建一个大的稀疏随机读写文件的话,我觉得这个过程可以更快一点。注意,普通关系数据库的存储实质是B+树的序列化,将内存指针转换为文件stream内的offset。这会涉及频繁的B+树分裂过程。

假如index的文件存储引擎就是一个hashmap的稀疏文件映射的话,麻烦的地方在于解决每个entry内部的变长字符串问题。也许变长字符串可以使用一个特殊的tag标记,指向一个单独的intern文件。intern文件是append-only类似于log文件格式的。(Ruby里面的symbolize)

嗯,Lucene的文件存储是怎么处理的呢???还有MongoDB呢???


看起来,从这个例子的分析可以看到:一个数据,至少有3种格式:内存存储、序列化/交换格式(stream)、文件存储格式。像这里的disk_cache simple index,以及MongoDB,估计都是把后2者合二为一了。所以它的初始load过程会比较慢。

 类似资料: