31.5.2. acestl::message_queue_sequence, 版本2
首先,我们需要知道何时可以进行块传输。ACE库基于char定义了不透明的内存块,也就是说指针的类型是char const*或者char*,大概是为了便于进行指针算术运算。这个策略我不敢苟同,但我的意见没什么用,ACE就是这么实现的。我们希望能够采用整块的方式,在char const*或char*类型的STL迭代器和acestl::message_queue_sequence::iterator之间传递内容。换句话说,以下代码应当调用两次memcpy(),而不是120次shared_handle::advance():
ACE_Message_Queue<ACE_NULL_SYNCH> mq; // 2 message blocks, 120 bytes char results[120]; acestl::message_queue_sequence<ACE_NULL_SYNCH> mqs(mq);
std::copy(mqs.begin(), mqs.end(), &results[120]);
|
从连续内存拷贝数据到消息队列时,我们也希望获得同样的效率,如下:
std::copy(&results[0], &results[0] + STLSOFT_NUM_ELEMENTS(results) , mqs.begin());
|
首要的事情是为message_queue_sequence定义块拷贝操作。清单31.10展示了该序列类新增的静态方法,fast_copy()重载。
清单 31.10. 定义message_queue_sequence 的算法辅助方法
Code View: Scroll / Show All template <ACE_SYNCH_DECL> class message_queue_sequence { . . . static char* fast_copy(iterator from, iterator to, char* o) { #if defined(ACESTL_MQS_NO_FAST_COPY_TO) for(; from != to; ++from, ++o) { *o = *from; } #else /* ACESTL_MQS_NO_FAST_COPY_TO */ from.fast_copy(to, o); #endif /* ACESTL_MQS_NO_FAST_COPY_TO */ return o; } static iterator fast_copy(char const* from, char const* to , iterator o) { #if defined(ACESTL_MQS_NO_FAST_COPY_FROM) for(;from != to; ++from, ++o) { *o = *from; } #else /* ACESTL_MQS_NO_FAST_COPY_FROM */ o.fast_copy(from, to); #endif /* ACESTL_MQS_NO_FAST_COPY_FROM */ return o; } . . . |
我故意留下了禁止块操作的#define语句,只是为了在代码中说明另一种,也就是缺省的行为是什么。这些#define还有一个作用,就是允许方便地在块拷贝打开和关闭的情况下进行测试。(我们即将进行性能测试,有人闻出味儿了吗?)块拷贝模式下的代码使用了新的iterator::fast_copy()方法,这些新方法如清单31.11所示。
清单 31.11. iterator 的算法辅助方法的定义
class message_queue_sequence<. . .>::iterator { . . . void fast_copy(char const* from, char const* to) { if(from != to) { ACESTL_ASSERT(NULL != m_handle); m_handle->fast_copy(from, to, static_cast<size_type>(to - from)); } } void fast_copy(class_type const& to, char* o) { if(*this != to) { ACESTL_ASSERT(NULL != m_handle); m_handle->fast_copy(to.m_handle, o); } } |
真是急人,上面的方法还是什么都没有做,基本上就只是调用了shared_handle类新定义的同名方法,如清单31.12所示。shared_handle类的方法计算出每个块需要读/写的部分,然后调用memcpy()进行传输。
清单 31.12. shared_handle的算法辅助方法的定义
Code View: Scroll / Show All struct message_queue_sequence<. . .>::iterator::shared_handle { . . . void fast_copy(char const* from, char const* to, size_type n) { ACESTL_ASSERT(0 != n); ACESTL_ASSERT(from != to); if(0 != n) { size_type n1 = m_entryLength - m_entryIndex; if(n <= n1) { ::memcpy(&m_entryIndex[m_entry->rd_ptr()], from, n); } else { ::memcpy(&m_entryIndex[m_entry->rd_ptr()], from, n1); from += n1; m_entry = nextEntry(); ACESTL_ASSERT(NULL != m_entry); fast_copy(from, to, n - n1); } } } void fast_copy(class_type const* to, char* o) { size_type n1 = m_entryLength - m_entryIndex; if( NULL != to && m_entry == to ->m_entry) { ::memcpy(o, &m_entryIndex[m_entry->rd_ptr()], n1); } else { ::memcpy(o, &m_entryIndex[m_entry->rd_ptr()], n1); o += n1; m_entry = nextEntry(); if(NULL != m_entry) { fast_copy(to, o); } } } . . . |
【责任编辑:
董书 TEL:(010)68476606】