Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
[C++] Получилось хорошее решение (но я испортил нитку в форуме). 19.12.07 07:50 Число просмотров: 2574
Автор: void <Grebnev Valery> Статус: Elderman Отредактировано 28.12.07 08:17 Количество правок: 4
|
Прошу прощения, но я испортил нитку. Я хотел "ответить" на свой постинг в корень но каким -то образом затёр своё первое сообщение. Администраторы/модераторы - я не хотел..... ;( Если можно, то исправьте плз.
-----
В общем получилось весьма универсальное и производительное решение, см ниже.
Не map, а всё ж вектор. Работает быстро. Решение годится (протестировано) для 2-х типов задач:
- когда для обновлений добавляются относительно "статичные" топики, например, статусные переменные, результаты запросов к базам данных и т.д. Такие топики могут быть добавлены в вектор при помощи TopicVector::AddTopic и обновлены Subscriber-ом по таймеру.
- когда обновляются относительно "быстрые" топики 10000-15000 раз в секунду, например, данные для Microsoft RTD (real time data server). Не вдаваясь в обсуждение майкрософтовской трактовки "real time data", скажу, что данные накапливаются в TopicVector по приходу обновлений для топика при помощи TopicVector::UpdateTopic. Главный трюк - когда приходит обновление устанавливаем topic->m_cRef ++ , а когда Subscriber получает обновления из TopicVector, то он сбрасывает эти значения topic->m_cRef = 0.
Таким образом, вектор содержит единственное "вхождение" топика (как map), а данные всегда актуальны. Это в разы быстрее, чем map.
В принципе, по результатам тестов - решение весьма производительно. Если же надо будет быстрее, то, думаю, вектор можно будет заменить массивом (может и на отдельном хипе). Сделать это будет легко, поскольку для TopicVector не предусматривается операции удаления/вставки отдельного элемента, а только добаление в хвост и очистка всего вектора.
#include <string>
#include <vector>
#include "comdef.h"
const int INVALIDE_TOPIC_ID = -1;
const int TOPICVECTOR_RESERVE_SIZE = 500000;
typedef variant_t topic_t;
class Topic {
public:
virtual topic_t GetValue(void) const PURE;
Topic(long ID = INVALIDE_TOPIC_ID) : m_topicID(ID), m_cRef(0L) {};
virtual ~Topic(){};
long m_topicID;
long m_cRef;
};
class TopicVector
{
public:
void AddTopic(Topic* topic)
{
m_vector.push_back(topic);
topic->m_cRef ++;
}
void UpdateTopic(Topic* topic)
{
if ( 0 == topic->m_cRef)
m_vector.push_back(topic);
topic->m_cRef ++;
}
size_t Size(void) const
{
return m_vector.size();
}
bool IsValidTopic(const size_t idx) const
{
if (NULL != m_vector.at(idx) && INVALIDE_TOPIC_ID != m_vector.at(idx)->m_topicID )
return true;
else
return false;
}
Topic* operator[](const size_t idx)
{
return m_vector.at(idx);
}
void Lock(void)
{
::EnterCriticalSection(&m_cs);
}
void Unlock(void)
{
::LeaveCriticalSection(&m_cs);
}
void Clear(void)
{
m_vector.clear();
}
TopicVector()
{
::InitializeCriticalSection(&m_cs);
m_vector.reserve(TOPICVECTOR_RESERVE_SIZE);
}
~TopicVector()
{
::DeleteCriticalSection(&m_cs);
}
private:
std::vector<Topic*> m_vector;
CRITICAL_SECTION m_cs;
};
|
- [C++] Получилось хорошее решение (но я испортил ни... - void 19.12.07 07:50 [2574]
|
|
|