最近在编写一个可以保存大量数据并可以对其按字段进行分区并按字段排序的数据结构,该结构分为内存和外存两种处理情况,当内存足以容纳下该批次数据量时,使用哈希结构(boost库的unordered_map)处理,当然这其中会加入一些自己的接口;当内存不足以容纳大批次数据的时候,就会使用外存,将所有数据按元数据结构全部写出到文件,这部分会使用到std的map结构以及归并排序的败者树算法,当需要写外存的时候,会有一种情况,数据是分区处理的,一次处理一个分区的数据,当一个分区的数据很大的时候,大到可用内存不足以容纳一个分区的时候,就要使用到PageFile的模式来处理,结构类似于下图,page的固定size根据情况而定,我取得是32K的大小,每个数据块的最后留出4个字节大小用来保存索引号,即当32k不足以容纳一个元数据结构时,就要再分一个page给它,依次类推,直到该元数据被全部写到文件中,最后一个page的索引号记为-1,用以标识该元数据块结束。


当对该分区的数据做处理的时候,根据此时要处理的数据的偏移计算出其属于的元数据的索引号,根据该索引号计算出该元数据保存的首页index索引,将其取出到内存中做相应处理,因为处理过程比较复杂,可能会对某块元数据反复的操作,所以为了提高程序的效率,减少IO操作,当处理完某一块元数据后并不会将其立即写回到文件中,但是由于内存无法容纳该分区的全部数据,所以就会出现某一个时刻,取出某一个数据块的时候,内存不够用了(我们有固定的结构来统计内存的使用情况,每块内存的申请或者释放都会经由该结构),这个时候就需要把某一个在内存中的数据块写回到文件中,但内存中会有许多个数据块,写哪一个?这个时候我采用的是LRU算法,我在将数据写出到内存的时候,会专门用一个结构来记录此时在内存中元数据的索引,当内存不够的时候,我可以知道此时哪些数据块正在被使用,而哪个数据块已经很久没使用了,我就将很久没使用的那个写回到文件中。

因为操作数据块的时候,可能会改写数据,即数据块的大小可能会发生变化,所以会出现一个数据块的所有page页并不是相邻的情况,这也是开始使用page页来处理的原因。

posted on 2016-06-22 15:37  LyndonYoung  阅读(238)  评论(0编辑  收藏  举报