天天看點

關于 Rocksdb 的 EnvWrapper 作用的小讨論

臨下班前一位做引擎的小夥伴提了個小問題, Rocksdb 實作了非常多的Env backend

關于 Rocksdb 的 EnvWrapper 作用的小讨論

這一些backend 可以讓使用者根據自己需求建立不同 公共接口backend,來實作自己的檔案操作或者公共線程池操作。

​Env* env = new rocksdb::HdfsEnv(FLAGS_hdfs)​

問題是,為什麼Rocksdb 這裡又多實作了一個​

​EnvWrapper​

​​ 類,​

​class EnvWrapper : public Env​

​​,其将​

​Env​

​ 幾乎所有的成員函數都用預設方式overrie了一遍,有必要嗎?

因為 ​

​Env​

​​的類中除了​

​Env* Default()​

​​ 之外的函數成員很多都已經是純虛函數了,它已經可以作為一個抽象類,來用其子類初始化該Env就可以了,那實作的這個​

​EnvWrapper​

​​ 中每一個函數都掉用一次​

​Env​

​ 基類 的對應實作完全沒有意義呀,想要實作自己的子類是不是隻需要繼承一下Env 基類就可以了,為什麼還需要單獨增加這兩百多行代碼?

大概看了一下 Rocksdb 内部是如何使用​

​EnvWrapper​

​的

關于 Rocksdb 的 EnvWrapper 作用的小讨論

可以看到有非常多的實作使用EnvWrapper,而在該類實作之前的注釋中可以很清晰得看到​

​EnvWrapper​

​的作用:

  1. 如果是隻有​

    ​Env​

    ​ 這個基類,那使用者實作自己的bakend 的時候就需要将裡面所有的純虛函數都實作一遍,這對很多使用者來說代價太高,有可能他們隻想修改其中一小部分函數,但卻要将所有的純虛函數override一遍。

    比如這個​

    ​NoSleepEnv​

    ​ 隻想要實作其中的幾個自己想用的函數就可以了,不需要受C++ 面向對象文法的限制了。
  2. Rocksdb 官方在Env 中增加了一些非常有用的純虛函數,對于使用者來說(繼承EnvWrapper 的使用者),自己不需要修改任何代碼就可以直接使用。

    比如,開發者在​

    ​Env​

    ​ 基類中增加了一個​

    ​virtual Status DisablePageCache() = 0​

    ​ 函數,同時同步到​

    ​EnvWrapper​

    ​中,這種情況下其他繼承自​

    ​EnvWrapper​

    ​ 統一類的使用者不需要修改自己的任何代碼,就可以直接使用在這個函數。否則,直接繼承​

    ​Env​

    ​ 實作自己的類的話 任何Env的改動都需要使用者修改自己的代碼。
上一篇: 圖靈的一生
下一篇: Jakarta ORO

繼續閱讀