HDF如何处理删除数据集释放的space而不重新打包
How does HDF handle the space freed by deleted datasets without repacking
我特别指的是 HDF 与使用 Pytables/Pandas 的接口,但我认为这通常适用于 HDF。
我知道 HDF 不会在删除数据集后回收 space,并且您必须使用 h5repack/ptrepack 回收 space。我对该方法的问题是,我发现这些工具非常慢,尤其是对于数 GB(我的文件约为 20 GB)的文件。所以 - 如果你必须 add/delete 具有某种规律性的派生数据集(比如,在调试生成该数据的东西时)
,那是不切实际的
所以 - 我的问题是 space 如果文件没有重新打包,数据集被删除会发生什么?在重新打包文件之前它是否丢失了?下次您尝试向文件 a-la SQL 写入内容时,它是否标记为可用于存储?换句话说 - 释放的 space 是否有用,或者您是否只需要经常重新打包文件?
我不知道 PyTables 背后的代码,所以无法给出官方的 PyTables 开发答案。在 PyTables Google Groups 站点提问,Francesc Alted 可能会回答。
在此期间,我写了一个小测试来锻炼这种行为。下面的示例已被修改以匹配我在 11 月 8 日的评论。它现在创建 3 个 HDF5 文件:
- 在第一个中,它创建了 5 个表
- 在第二个中,它创建了 5 个表,然后将其删除,然后又创建了 5 个表(具有不同的名称)
- 第三个创建了5个表,关闭了文件。重新打开文件,删除 5 个表,然后关闭文件。文件被重新打开,又创建了 5 个表(具有不同的名称)。
生成的文件大小相同。
我的结论:PyTables 足够聪明,可以在新表与删除表的大小相同时回收分配的(但未使用的)space。我怀疑如果新表更大,您可能会得到不同的结果。
下面的简单示例:
文件 _1、_2 和 _3 在我的测试中都是 114 MB。
import tables as tb
import numpy as np
data1 = np.arange(1000000.)
data2 = 2.0*data1
data3 = 3.0*data1
ds_dt = np.dtype({'names':['data1', 'data2', 'data3'],
'formats':[(float), (float), (float)] })
rec_arr = np.rec.fromarrays([data1, data2, data3], dtype=ds_dt)
with tb.File('SO_58736920_1.h5','w') as h5f:
tb1 = h5f.create_table('/','test1',obj=rec_arr)
tb2 = h5f.create_table('/','test2',obj=rec_arr)
tb3 = h5f.create_table('/','test3',obj=rec_arr)
tb4 = h5f.create_table('/','test4',obj=rec_arr)
tb5 = h5f.create_table('/','test5',obj=rec_arr)
with tb.File('SO_58736920_2.h5','w') as h5f:
tb1 = h5f.create_table('/','test1',obj=rec_arr)
tb2 = h5f.create_table('/','test2',obj=rec_arr)
tb3 = h5f.create_table('/','test3',obj=rec_arr)
tb4 = h5f.create_table('/','test4',obj=rec_arr)
tb5 = h5f.create_table('/','test5',obj=rec_arr)
tb1._f_remove()
tb2._f_remove()
tb3._f_remove()
tb4._f_remove()
tb5._f_remove()
tb11 = h5f.create_table('/','test11',obj=rec_arr)
tb12 = h5f.create_table('/','test12',obj=rec_arr)
tb13 = h5f.create_table('/','test13',obj=rec_arr)
tb14 = h5f.create_table('/','test14',obj=rec_arr)
tb15 = h5f.create_table('/','test15',obj=rec_arr)
with tb.File('SO_58736920_3.h5','w') as h5f:
tb1 = h5f.create_table('/','test1',obj=rec_arr)
tb2 = h5f.create_table('/','test2',obj=rec_arr)
tb3 = h5f.create_table('/','test3',obj=rec_arr)
tb4 = h5f.create_table('/','test4',obj=rec_arr)
tb5 = h5f.create_table('/','test5',obj=rec_arr)
with tb.File('SO_58736920_3.h5','r+') as h5f:
h5f.root.test1._f_remove()
h5f.root.test2._f_remove()
h5f.root.test3._f_remove()
h5f.root.test4._f_remove()
h5f.root.test5._f_remove()
with tb.File('SO_58736920_3.h5','r+') as h5f:
tb11 = h5f.create_table('/','test11',obj=rec_arr)
tb12 = h5f.create_table('/','test12',obj=rec_arr)
tb13 = h5f.create_table('/','test13',obj=rec_arr)
tb14 = h5f.create_table('/','test14',obj=rec_arr)
tb15 = h5f.create_table('/','test15',obj=rec_arr)
我特别指的是 HDF 与使用 Pytables/Pandas 的接口,但我认为这通常适用于 HDF。
我知道 HDF 不会在删除数据集后回收 space,并且您必须使用 h5repack/ptrepack 回收 space。我对该方法的问题是,我发现这些工具非常慢,尤其是对于数 GB(我的文件约为 20 GB)的文件。所以 - 如果你必须 add/delete 具有某种规律性的派生数据集(比如,在调试生成该数据的东西时)
,那是不切实际的所以 - 我的问题是 space 如果文件没有重新打包,数据集被删除会发生什么?在重新打包文件之前它是否丢失了?下次您尝试向文件 a-la SQL 写入内容时,它是否标记为可用于存储?换句话说 - 释放的 space 是否有用,或者您是否只需要经常重新打包文件?
我不知道 PyTables 背后的代码,所以无法给出官方的 PyTables 开发答案。在 PyTables Google Groups 站点提问,Francesc Alted 可能会回答。 在此期间,我写了一个小测试来锻炼这种行为。下面的示例已被修改以匹配我在 11 月 8 日的评论。它现在创建 3 个 HDF5 文件:
- 在第一个中,它创建了 5 个表
- 在第二个中,它创建了 5 个表,然后将其删除,然后又创建了 5 个表(具有不同的名称)
- 第三个创建了5个表,关闭了文件。重新打开文件,删除 5 个表,然后关闭文件。文件被重新打开,又创建了 5 个表(具有不同的名称)。
生成的文件大小相同。
我的结论:PyTables 足够聪明,可以在新表与删除表的大小相同时回收分配的(但未使用的)space。我怀疑如果新表更大,您可能会得到不同的结果。
下面的简单示例: 文件 _1、_2 和 _3 在我的测试中都是 114 MB。
import tables as tb
import numpy as np
data1 = np.arange(1000000.)
data2 = 2.0*data1
data3 = 3.0*data1
ds_dt = np.dtype({'names':['data1', 'data2', 'data3'],
'formats':[(float), (float), (float)] })
rec_arr = np.rec.fromarrays([data1, data2, data3], dtype=ds_dt)
with tb.File('SO_58736920_1.h5','w') as h5f:
tb1 = h5f.create_table('/','test1',obj=rec_arr)
tb2 = h5f.create_table('/','test2',obj=rec_arr)
tb3 = h5f.create_table('/','test3',obj=rec_arr)
tb4 = h5f.create_table('/','test4',obj=rec_arr)
tb5 = h5f.create_table('/','test5',obj=rec_arr)
with tb.File('SO_58736920_2.h5','w') as h5f:
tb1 = h5f.create_table('/','test1',obj=rec_arr)
tb2 = h5f.create_table('/','test2',obj=rec_arr)
tb3 = h5f.create_table('/','test3',obj=rec_arr)
tb4 = h5f.create_table('/','test4',obj=rec_arr)
tb5 = h5f.create_table('/','test5',obj=rec_arr)
tb1._f_remove()
tb2._f_remove()
tb3._f_remove()
tb4._f_remove()
tb5._f_remove()
tb11 = h5f.create_table('/','test11',obj=rec_arr)
tb12 = h5f.create_table('/','test12',obj=rec_arr)
tb13 = h5f.create_table('/','test13',obj=rec_arr)
tb14 = h5f.create_table('/','test14',obj=rec_arr)
tb15 = h5f.create_table('/','test15',obj=rec_arr)
with tb.File('SO_58736920_3.h5','w') as h5f:
tb1 = h5f.create_table('/','test1',obj=rec_arr)
tb2 = h5f.create_table('/','test2',obj=rec_arr)
tb3 = h5f.create_table('/','test3',obj=rec_arr)
tb4 = h5f.create_table('/','test4',obj=rec_arr)
tb5 = h5f.create_table('/','test5',obj=rec_arr)
with tb.File('SO_58736920_3.h5','r+') as h5f:
h5f.root.test1._f_remove()
h5f.root.test2._f_remove()
h5f.root.test3._f_remove()
h5f.root.test4._f_remove()
h5f.root.test5._f_remove()
with tb.File('SO_58736920_3.h5','r+') as h5f:
tb11 = h5f.create_table('/','test11',obj=rec_arr)
tb12 = h5f.create_table('/','test12',obj=rec_arr)
tb13 = h5f.create_table('/','test13',obj=rec_arr)
tb14 = h5f.create_table('/','test14',obj=rec_arr)
tb15 = h5f.create_table('/','test15',obj=rec_arr)