>buffer_manager
idle_id_cont // 空闲的buffer id
writed_id_cont // 空闲的buffer id,不过已经被write
parsed_id_cont // 空闲的buffer id,不过已经被parse
buffer_cont // 缓冲区集合
mutex // 互斥对象
>buffer
data // 数据
flag // 初始化为0, 当被write or parse 时把他设置为 !flag 。
// 也就是说,如果某个write/parse 线程返回该缓冲,
// 且flag==0 时,说明该缓冲数据可以删除。
// [函数都用mutex互斥]
// [请求缓冲区]
buffer*buffer_manager::request_buffer(int type,int& buffer_id/*[out]*/) ;
// [归还缓冲区]
void buffer_manager::return_buffer(buffer* ret_buffer,int type);
// [清空缓冲区]
void clear_buffer();
Buffer* buffer_manager::request_buffer(int type,int& buffer_id/*[out]*/)
{
// [当然可以针对每个 case 写一处理函数!]
switch(type)
{
case type_spider:
for(id in idle_id_cont)
{
// [由于下面限制了writed_id_cont.size() + parsed_id_cont.size()
//个数小于或者等于 n ,因此spider 肯定会分配到空闲buffer]
if(!(id in writed_id_cont) && !(id in parsed_id_cont))
{
idle_id_cont.remove(id);
buffer_id = id;
return buffer_cont[id];
}
}
break;
// [provided n is sum of (count of writer and parser threads) ]
case type_writer:
if(n <= writed_id_cont.size() + parsed_id_cont.size())
// [不分配给该writer 线程,避免出现spider等待]
return NULL;
// [优先分配已经被parse的缓冲]
if(!parsed_id_cont.empty())
{
buf_id = parsed_id_cont.back();
parsed_id_cont.pop_back();
idle_id_cont.remove(buf_id);
buffer_id = buf_id;
return buffer_cont[buf_id];
}
else
{
buf_id = idle_id_cont.back();
idle_id_cont.pop_back();
buffer_id = buf_id;
return buffer_cont[buf_id];
}
break;
case type_parser:
if(n <= writed_id_cont.size() + parsed_id_cont.size())
// [不分配给该writer 线程,避免出现spider等待]
return NULL;
// [优先分配已经被write的缓冲]
if(!writed_id_cont.empty())
{
buf_id = writed_id_cont.back();
writed_id_cont.pop_back();
idle_id_cont.remove(buf_id);
buffer_id = buf_id;
return buffer_cont[buf_id];
}
else
{
buf_id = idle_id_cont.back();
idle_id_cont.pop_back();
buffer_id = buf_id;
return buffer_cont[buf_id];
}
break;
}
}
// [归还缓冲区]
void buffer_manager::return_buffer(int buffer_id,int type)
{
// [可以针对每个 case 写一处理函数!]
switch(type)
{
case type_writer:
buffer * pbf = buffer_cont[buffer_id];
pbf->flag = !pbf->flag;
if(pbf->flag)
writed_id_cont.push_back(buffer_id);
else
clear_buffer(buffer_id);
break;
case type_parser:
buffer * pbf = buffer_cont[buffer_id];
pbf->flag = !pbf->flag;
if(pbf->flag)
parsed_id_cont.push_back(buffer_id);
else
clear_buffer(buffer_id);
break;
}
idle_id_cont.push_back(buffer_id);
}