
如果当前的记录是当前最小的记录,则将当前的存储集中的下一条记录拉取到滑动窗口中替换。如下图所示,假如第一轮中的存储集2中的记录1符合条件,最先进行输出,然后需要将存储集2中的下一条记录拉取到滑动窗口中进行下一轮输出,如果没有记录,则用NULL代替存储。

下面我们以C++为例,写一下记录和存储集的定义格式,如下。
class MenRecord{ //拉取的一条记录//省略定义......public:long long timestamp;char* pData;};class MemResult{ //定义结果集MenRecord* Read(){if(m_read_index < m_Record_Size)return pRecord[m_read_index++];return NULL;};//判断当前存储集中是否 还有未处理记录bool Readable() {return (m_read_index<m_Record_Size)};private:int m_write_index;int m_read_index;int m_Record_Size; //记录的条数MenRecord* pRecord;//记录};
接下来,我们重点实现MemDataOrderImpl类的Read方法即可。
class MemDataOrderImpl{public:void Read(buffer* buff);private:std::vector<MemResult*> myMemResultVec; //所有存储集的对象};
实现如下:
void MemDataOrderImpl::Read(buffer* buff){std::vector<MenRecord*> MemRcdVec;//先从每一个存储集中获得第一轮的记录数for(int i=0;i<myMemResultVec.size();i++){MemRcdVec.push_back(myMemResultVec[i].Read());}//开始处理while(true){//计算得到当前滑动窗口中的 最小记录long long ll_time_stamp = MAX_LONG;int m_index_for_current_round = 0; //当前轮的最小记录//针对当前 滑动窗口中记录 进行处理,得到最小记录for(int i=0;i<MemRcdVec.size();i++){if(MemRcdVec[i]){if(MemRcdVec[i]->timestamp < ll_time_stamp ){ll_time_stamp = MemRcdVec[i]->timestamp;m_index_for_current_round = i;}}}//输出当前记录,更新滑动窗口MemRcdVec[m_index_for_current_round] =myMemResultVec[m_index_for_current_round].Read();//当每个存储集合中数据处理完成,跳出循环bool b_exit_flag = true;for(int i=0;i<myMemResultVec.size();i++){if(myMemResultVec[i].Readable()){b_exit_flag = false;//如果还有未处理数据break;}}if(b_exit_flag )break;}}
void Read(buffer* buff, int max_record_cnt);
class IDataInterface{//读取全部记录,写入缓冲区buff中virtual void Read(buffer* buff) = 0;//读取最多max_record_size记录数,并写入buff中virtual void Read(buffer* buff, int max_record_size) =0;//写入内存块,包括size记录数virtual void Write(MemResult*,int size) = 0 ;};
总结:如果记录是链表存储的,则滑动窗口可以采用最小堆的方式,每次取出堆顶记录,同时获得下一条记录。但是目前每一个记录都是数组存储的连续内存块,则只能用这种对齐方式进行处理。
文章转载自码农的修炼之道,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




