时序:
接上文,不啰嗦了。
【定义】:
/* CLASS_BEGIN *****************************************************
类名: CIMGroupMemberCache
功能: 分布式缓存群组Member信息
1. 群组成员信息缓存、更新及
2. 数据库访问
版本: V1.0
时间: 2012-3-16 创建
实现: Snight Q:51171107
CLASS_END ******************************************************/
#ifndef H_IMGROUPMEMBERCACHE_H
#define H_IMGROUPMEMBERCACHE_H
#include "SImGroupDbRead.h"
#include "SImGroupDbWrite.h"
#include "CThreadLock.h"
#include "CThreadMgr.h"
#include "LoadConfig.h"
#include "CGroupDefine.h"
#include "IMGroupDbCache.h"
#include "ITransmitter.h"
#include <hash_map>
#include <map>
class CIMGroupMemberCache
{
public:
~CIMGroupMemberCache(void);
// 读取单例对象
static CIMGroupMemberCache* GetSigoObj(void);
// 释放单例对象
static void FreeSigoObj(void);
public:
// 初始化缓存
BOOL InitCache(CIMGroupDbCache* apImGroupDbCache);
// 反初始化
BOOL UnInitCache(void);
// 读取群成员信息
S_GroupMember* GetGroupMember(SInt64 ai64UserID, SInt64 aiGroupID);
// 读取群组信息
S_GroupInfo* GetGroupInfo(SInt64 aiGroupID);
// 添加检查成员
BOOL AddCheckMember(SInt64 aiUserID, sockaddr_in* apAddr);
// 读取检查成员
sockaddr_in GetCheckMemberAddr(SInt64 aiUserID, sockaddr_in& aoSAddr);
// 为成员增加地址信息
void AddMemberAddr(SInt64 aiUserID, sockaddr_in& aoSAddr);
// 获取群成员地址信息
sockaddr_in* GetMemberAddr(SInt64 aiUserID);
public:
// 群组成员信息变化最大值读取
BOOL GetGroupMemberChangeLast(SInt64& aiLastID);
// 群组成员名片变化最大值读取
BOOL GetGroupMbBscardChangeLast(SInt64& aiLastID);
// 通知群成员变化,更群成员缓存
BOOL NoticeGroupMemberChangeByLastID(ITransmitter* apTransMiter);
// 通知群组人员用户信息发生变化
BOOL NoticeGroupMemberChange(S_GroupInfo* apGroupInfo,
S_GroupMember* apMembersInfo,
ITransmitter* apTransMiter,
SInt8 ai8ChangeType);
// 通知群成员名片变化,更新成员名片缓存
BOOL NoticeGroupMbBscardChangeByLastID(ITransmitter* apTransMiter);
BOOL NoticeGroupMemberBsCardChange(S_GroupInfo* apGroupInfo,
S_GroupMemberBsCard* apMembersInfo,
ITransmitter* apTransMiter,
SInt8 ai8ChangeType);
// 批量插入或更新群成员信息
BOOL ChangeGroupMemberBatch( SInt64 ai64GroupID, SInt64 ai64UID,SInt16 m_i16UserIdentity,
SInt64 m_li64CreateDateTime,SInt8 m_i8ChangeType);
// 批量插入或更新群名片信息
BOOL ChangeGroupMbBsCardBatch( SInt64 ai64GroupID,SInt64 ai64UID, Byte abySex, char* apName,
char* apTelNum, char* apEmail, char* apReMarks, SInt8 ai8ChangeType);
private:
BOOL ChangeGroupMemberBatch(void);
BOOL ChangeGroupMemberBatch(std::vector<S_GroupMember*>* apMemberArray);
BOOL ChangeGroupMbBsCardBatch(void);
BOOL ChangeGroupMbBsCardBatch(std::vector<S_GroupMemberBsCard*>* apMbBsCardArray);
private:
CIMGroupMemberCache(void);
// 工作线程
static ULong WorkThread(void* apThis);
void WorkThread(void);
private:
BOOL m_bIsInit;
static CIMGroupMemberCache* m_pSigoObj; // 单例对象
CMemPool* m_pMemPool; // 内存池
SInt64 m_i64GroupMbChLastId; // 群成员变化最大值
SInt64 m_i64GroupMbBsCardChLastId; // 群成员名片变化最大值
std::map<SInt64, S_GroupInfo*> m_oGroupMemberInfoMap; // 群成员缓存表
CThreadLock m_oGroupMemberInfoMapLock; // 群成员缓存表锁
std::map<SInt64, S_GroupMbCheck*> m_oGMemberCheckMap; // 群成员登录超时检查表
CThreadLock m_oGMemberCheckMapLock; // 群成员登录超时检查表锁
std::map<SInt64, sockaddr_in*> m_oGMemberAddrMap; // 群成员地址信息
CThreadLock m_oGMemberAddrMapLock; // 群成员地址信息锁
CIMGroupDbCache* m_pImGroupDbCache; // 数据库访问缓存
std::map<SInt64, std::vector<S_GroupMember*>* > m_oGroupMemberChangeMap; // 群成员变化表
CThreadLock m_oGroupMemberChangeMapLock; // 群成员变化表锁
std::map<SInt64, std::vector<S_GroupMemberBsCard*>* > m_oGroupMbBsCardChangeMap; // 群成员名片变化表
CThreadLock m_oGroupMbBsCardChangeMapLock; // 群成员名片变化表锁
};
#endif//H_IMGROUPMEMBERCACHE_H
【实现】:
#include "IMGroupMemberCache.h"
#include "ImGroupSvrPag.h"
#include "CRunningLog.h"
#include "CPubfuncs.h"
// init sigo obj
CIMGroupMemberCache* CIMGroupMemberCache::m_pSigoObj = NULL;
CIMGroupMemberCache::CIMGroupMemberCache(void)
: m_bIsInit(FALSE)
, m_i64GroupMbChLastId(-1)
, m_i64GroupMbBsCardChLastId(-1)
, m_pImGroupDbCache(NULL)
{
m_pMemPool = CMemPool::GetPool();
}
CIMGroupMemberCache::~CIMGroupMemberCache(void)
{
}
// 读取单例对象
CIMGroupMemberCache* CIMGroupMemberCache::GetSigoObj(void)
{
if(!m_pSigoObj)
m_pSigoObj = new CIMGroupMemberCache;
return m_pSigoObj;
}
// 释放单例对象
void CIMGroupMemberCache::FreeSigoObj(void)
{
if (m_pSigoObj)
{
m_pSigoObj->UnInitCache();
delete m_pSigoObj;
}
}
// 初始化缓存
BOOL CIMGroupMemberCache::InitCache(CIMGroupDbCache* apImGroupDbCache)
{
if (m_bIsInit) return TRUE;
if (apImGroupDbCache)
m_pImGroupDbCache = apImGroupDbCache;
CThreadMgr loTdMgr;
loTdMgr.BeginThread(WorkThread , this);
return TRUE;
}
BOOL CIMGroupMemberCache::UnInitCache(void)
{
return TRUE;
}
// 读取群成员变化,更群成员缓存
BOOL CIMGroupMemberCache::NoticeGroupMemberChangeByLastID(ITransmitter* apTransMiter)
{
BOOL lbResult = FALSE;
SInt64 liBegTime = CPubfuncs::GetCurTime();
AutoDbReaderPtr lpDbReader(m_pImGroupDbCache);
if (lpDbReader.IsAvailable())
{
SInt64 liBeg = m_i64GroupMbChLastId;
std::vector<S_GroupMember*> loMembers;
if(0 == lpDbReader->GetGroupMemberChangeByLastID(m_i64GroupMbChLastId, MySql_PageSize, loMembers))
{
INFO_LOG("INFO: 读取群组成员变化 LastID:[%I64d] 更新记录数:[%d] 耗时:[%I64d]",m_i64GroupMbChLastId, loMembers.size(), (CPubfuncs::GetCurTime() - liBegTime));
if (m_i64GroupMbChLastId < liBeg) m_i64GroupMbChLastId = liBeg+1;
lbResult = TRUE;
}
S_GroupMember* lpMembers = NULL;
S_GroupMember* lpMembersFind = NULL;
S_GroupInfo* lpGroupInfo = NULL;
std::vector<S_GroupMember*>::iterator liIter;
std::map<SInt64, S_GroupInfo*>::iterator liMapIter;
std::map<SInt64, S_GroupMember*>::iterator liGMemberIter;
for (liIter = loMembers.begin(); liIter != loMembers.end(); ++liIter)
{
if (lpMembers = *liIter)
{
m_oGroupMemberInfoMapLock.lock();
// 如果该群组是在缓存中
if ((liMapIter = m_oGroupMemberInfoMap.find(lpMembers->m_i64GroupID)) != m_oGroupMemberInfoMap.end())
{
// 有效群组缓存
if (lpGroupInfo = liMapIter->second)
{
// 该成员隶属于该群组
if ((liGMemberIter = lpGroupInfo->m_oGroupMember.find(lpMembers->m_i64UID)) != lpGroupInfo->m_oGroupMember.end())
{
lpMembersFind = liGMemberIter->second;
lpGroupInfo->m_oGroupMember.erase(liGMemberIter);
lpGroupInfo->m_oGroupManager.erase(lpMembers->m_i64UID);
}
S_GroupMember* lpRecordMember = NULL;
SInt8 li8Type = 1;//新增或修改
switch(lpMembers->m_i8ChangeType)
{
case MySql_Add:
case MySql_Update:
{
lpRecordMember = new S_GroupMember();
if (lpRecordMember)
{
lpRecordMember->m_i64GroupID = lpMembers->m_i64GroupID;
lpRecordMember->m_i64UID = lpMembers->m_i64UID;
lpRecordMember->m_i16UserIdentity = lpMembers->m_i16UserIdentity;
lpRecordMember->m_li64CreateDateTime = lpMembers->m_li64CreateDateTime;
lpRecordMember->m_li64ChangeDateTime = lpMembers->m_li64ChangeDateTime;
if (lpMembersFind)
{
lpRecordMember->m_pSockAddr = lpMembersFind->m_pSockAddr;
lpRecordMember->m_pMemberBsCard = lpMembersFind->m_pMemberBsCard;
}
lpGroupInfo->m_oGroupManager.insert(std::make_pair(lpRecordMember->m_i64UID ,lpRecordMember));
if (lpRecordMember->m_i16UserIdentity == 1)
lpGroupInfo->m_oGroupManager.insert(std::make_pair(lpRecordMember->m_i64UID ,lpRecordMember));
}
break;
}
case MySql_Del:
li8Type = 0;
default:
break;
}
if (lpMembersFind)
delete lpMembersFind;
// 通知群组人员用户信息发生变化
NoticeGroupMemberChange(lpGroupInfo, lpRecordMember, apTransMiter, li8Type);
}
}
m_oGroupMemberInfoMapLock.unlock();
delete lpMembers;
}
}
}
return lbResult;
}
BOOL CIMGroupMemberCache::NoticeGroupMemberChange(S_GroupInfo* apGroupInfo, S_GroupMember* apMembersInfo, ITransmitter* apTransMiter, SInt8 ai8ChangeType)
{
if((apGroupInfo)&&(apMembersInfo)&&(apTransMiter))
{
S_GroupMember* lpMembersFind = NULL;
std::map<SInt64, S_GroupMember*>::iterator liGMemberIter;
STRU_GROUP_SVR_GMEMBER_ID loGMemberID;
loGMemberID.m_i64GroupID = apMembersInfo->m_i64GroupID;
loGMemberID.m_i64UID = 0;
loGMemberID.m_iMemberCnt = 1;
loGMemberID.m_pMemberBuffer = new STRU_GROUP_SVR_MEMBER;
if(loGMemberID.m_pMemberBuffer)
{
loGMemberID.m_pMemberBuffer->m_i64UID = apMembersInfo->m_i64UID;
loGMemberID.m_pMemberBuffer->m_i64GroupID = apMembersInfo->m_i64GroupID;
loGMemberID.m_pMemberBuffer->m_i16UserIdentity = apMembersInfo->m_i16UserIdentity;
loGMemberID.m_pMemberBuffer->m_li64CreateDateTime = apMembersInfo->m_li64CreateDateTime;
loGMemberID.m_pMemberBuffer->m_i8ChangeType = ai8ChangeType;
UInt16 li16Len = 0;
char* lpBuffer = loGMemberID.Pack(li16Len);
if ((li16Len>0) && (lpBuffer))
{
for (liGMemberIter = apGroupInfo->m_oGroupMember.begin(); liGMemberIter != apGroupInfo->m_oGroupMember.end(); ++liGMemberIter)
{
if ((lpMembersFind = liGMemberIter->second)&&(lpMembersFind->m_pSockAddr))
apTransMiter->SendUdpData(lpBuffer, li16Len, lpMembersFind->m_pSockAddr);
}
}
if (lpBuffer)m_pMemPool->FreeBuffer(lpBuffer);
delete loGMemberID.m_pMemberBuffer;
}
return TRUE;
}
return FALSE;
}
// 读取群成员名片变化,更新成员名片缓存
BOOL CIMGroupMemberCache::NoticeGroupMbBscardChangeByLastID(ITransmitter* apTransMiter)
{
BOOL lbResult = FALSE;
SInt64 liBegTime = CPubfuncs::GetCurTime();
AutoDbReaderPtr lpDbReader(m_pImGroupDbCache);
if (lpDbReader.IsAvailable())
{
SInt64 liBeg = m_i64GroupMbBsCardChLastId;
std::vector<S_GroupMemberBsCard*> loMemberBsCardChange;
if(0 == lpDbReader->GetGroupMbBscardChangeByLastID(m_i64GroupMbBsCardChLastId, MySql_PageSize, loMemberBsCardChange))
{
INFO_LOG("INFO: 读取群组成员名片变化 LastID:[%I64d] 更新记录数:[%d] 耗时:[%I64d]",
m_i64GroupMbBsCardChLastId, loMemberBsCardChange.size(), (CPubfuncs::GetCurTime() - liBegTime));
if (m_i64GroupMbBsCardChLastId < liBeg)
m_i64GroupMbBsCardChLastId = liBeg+1;
lbResult = TRUE;
}
S_GroupMemberBsCard* lpMbBsCard = NULL;
S_GroupMember* lpMembersFind = NULL;
S_GroupInfo* lpGroupInfo = NULL;
std::vector<S_GroupMemberBsCard*>::iterator liBsCardIter;
std::map<SInt64, S_GroupInfo*>::iterator liMapIter;
std::map<SInt64, S_GroupMember*>::iterator liGMemberIter;
for (liBsCardIter = loMemberBsCardChange.begin(); liBsCardIter != loMemberBsCardChange.end(); ++liBsCardIter)
{
if (lpMbBsCard = *liBsCardIter)
{
m_oGroupMemberInfoMapLock.lock();
// 如果该群组是在缓存中
if ((liMapIter = m_oGroupMemberInfoMap.find(lpMbBsCard->m_i64GroupID)) != m_oGroupMemberInfoMap.end())
{
// 有效群组缓存
if (lpGroupInfo = liMapIter->second)
{
// 该成员隶属于该群组
if ((liGMemberIter = lpGroupInfo->m_oGroupMember.find(lpMbBsCard->m_i64UID)) != lpGroupInfo->m_oGroupMember.end())
{
lpMembersFind = liGMemberIter->second;
}
if (lpMembersFind)
{
if (NULL == lpMembersFind->m_pMemberBsCard)
lpMembersFind->m_pMemberBsCard = new S_GroupMemberBsCard();
SInt8 ai8ChangeType = 1;
if (lpMembersFind->m_pMemberBsCard)
{
switch(lpMbBsCard->m_i8ChangeType)
{
case MySql_Add:
case MySql_Update:
{
*lpMembersFind->m_pMemberBsCard = *lpMbBsCard;
break;
}
case MySql_Del:
{
delete lpMembersFind->m_pMemberBsCard;
lpMembersFind->m_pMemberBsCard = NULL;
ai8ChangeType = 0;
break;
}
default:
break;
}
}
if (lpMembersFind->m_pMemberBsCard)
NoticeGroupMemberBsCardChange(lpGroupInfo, lpMembersFind->m_pMemberBsCard, apTransMiter,ai8ChangeType);
}
}
else
m_oGroupMemberInfoMap.erase(liMapIter);
}
m_oGroupMemberInfoMapLock.unlock();
delete lpMbBsCard;
}
}
}
return lbResult;
}
BOOL CIMGroupMemberCache::NoticeGroupMemberBsCardChange(S_GroupInfo* apGroupInfo,
S_GroupMemberBsCard* apMembersInfo,
ITransmitter* apTransMiter,
SInt8 ai8ChangeType)
{
if((apGroupInfo)&&(apMembersInfo)&&(apTransMiter))
{
S_GroupMember* lpMembersFind = NULL;
std::map<SInt64, S_GroupMember*>::iterator liGMemberIter;
STRU_GROUP_SVR_GMEMBER_BSCARD_ID loGMemberBsCardID;
loGMemberBsCardID.m_i64GroupID = apGroupInfo->m_i64GroupID;
loGMemberBsCardID.m_i64BsCardUID = apMembersInfo->m_i64UID;
loGMemberBsCardID.m_i64ApplyerUID = 0;
loGMemberBsCardID.m_i8ChangeType = ai8ChangeType;
loGMemberBsCardID.m_bySex = apMembersInfo->m_bySex;
loGMemberBsCardID.m_i16NameLen = strlen(apMembersInfo->m_pName);
if ((loGMemberBsCardID.m_i16NameLen > 20) || loGMemberBsCardID.m_i16NameLen <0)
loGMemberBsCardID.m_i16NameLen = 20;
memset(loGMemberBsCardID.m_szName, 0, sizeof(char)*21);
memcpy(loGMemberBsCardID.m_szName, apMembersInfo->m_pName, loGMemberBsCardID.m_i16NameLen*sizeof(char));
loGMemberBsCardID.m_i16TelNumLen = strlen(apMembersInfo->m_pTelNum);
if ((loGMemberBsCardID.m_i16TelNumLen > 40) || loGMemberBsCardID.m_i16TelNumLen <0)
loGMemberBsCardID.m_i16TelNumLen = 40;
memset(loGMemberBsCardID.m_szTelNum, 0, sizeof(char)*41);
memcpy(loGMemberBsCardID.m_szTelNum, apMembersInfo->m_pTelNum, loGMemberBsCardID.m_i16TelNumLen*sizeof(char));
loGMemberBsCardID.m_i16EmailLen = strlen(apMembersInfo->m_pEmail);
if ((loGMemberBsCardID.m_i16EmailLen > 100) || loGMemberBsCardID.m_i16EmailLen < 0)
loGMemberBsCardID.m_i16EmailLen = 100;
memset(loGMemberBsCardID.m_szEmail, 0, sizeof(char)*101);
memcpy(loGMemberBsCardID.m_szEmail, apMembersInfo->m_pEmail, loGMemberBsCardID.m_i16EmailLen*sizeof(char));
loGMemberBsCardID.m_i16ReMarksLen = strlen(apMembersInfo->m_pReMarks);
if ((loGMemberBsCardID.m_i16ReMarksLen > 120) || loGMemberBsCardID.m_i16ReMarksLen < 0)
loGMemberBsCardID.m_i16ReMarksLen = 120;
memset(loGMemberBsCardID.m_szReMarks, 0, sizeof(char)*121);
memcpy(loGMemberBsCardID.m_szReMarks,apMembersInfo->m_pReMarks, loGMemberBsCardID.m_i16ReMarksLen*sizeof(char));
UInt16 li16Len = 0;
char* lpBuffer = loGMemberBsCardID.Pack(li16Len);
if ((li16Len > 0)&&(lpBuffer))
{
for (liGMemberIter = apGroupInfo->m_oGroupMember.begin(); liGMemberIter != apGroupInfo->m_oGroupMember.end(); ++liGMemberIter)
{
if ((lpMembersFind = liGMemberIter->second)&&(lpMembersFind->m_pSockAddr))
apTransMiter->SendUdpData(lpBuffer, li16Len, lpMembersFind->m_pSockAddr);
}
}
if (lpBuffer)m_pMemPool->FreeBuffer(lpBuffer);
}
return FALSE;
}
ULong CIMGroupMemberCache::WorkThread(void* apThis)
{
if (NULL != apThis)
{
CIMGroupMemberCache* lpThis = (CIMGroupMemberCache*)apThis;
lpThis->WorkThread();
}
return 1;
}
void CIMGroupMemberCache::WorkThread(void)
{
Sleep(3000);
// 初始化完成
m_bIsInit = TRUE;
// 群组成员信息变化最大值读取
GetGroupMemberChangeLast(m_i64GroupMbChLastId);
INFO_LOG("INFO: 群组成员信息变化最大值 m_i64GroupMbChLastId:%I64d ", m_i64GroupMbChLastId);
// 群组成员名片变化最大值读取
GetGroupMbBscardChangeLast(m_i64GroupMbBsCardChLastId);
INFO_LOG("INFO: 群组成员名片变化最大值 m_i64GroupMbBsCardChLastId:%I64d ", m_i64GroupMbBsCardChLastId);
SInt64 liGMemberChangeBatch = CPubfuncs::GetCurTime();
SInt64 liGMbBsCardChangeBatch = CPubfuncs::GetCurTime();
SInt64 li64MbCheck = CPubfuncs::GetCurTime();
while (m_bIsInit)
{
// 异步插入或更新群组成员信息
if ((CPubfuncs::GetCurTime() - liGMemberChangeBatch) > DEF_SECOND*5)
{
liGMemberChangeBatch = CPubfuncs::GetCurTime();
ChangeGroupMemberBatch();
}
// 异步插入或更新群组成员名片信息
if ((CPubfuncs::GetCurTime() - liGMbBsCardChangeBatch) > DEF_SECOND*5)
{
liGMbBsCardChangeBatch = CPubfuncs::GetCurTime();
ChangeGroupMbBsCardBatch();
}
// 清除超时的用户检查
if ((CPubfuncs::GetCurTime() - li64MbCheck) > DEF_SECOND*5)
{
li64MbCheck = CPubfuncs::GetCurTime();
S_GroupMbCheck* lpMbCheck = NULL;
std::map<SInt64, S_GroupMbCheck*>::iterator liIter;
// m_oGMemberCheckMapLock.lock();
// liIter = m_oGMemberCheckMap.begin();
// while (liIter != m_oGMemberCheckMap.end())
// {
// if (lpMbCheck = liIter->second)
// {
// if ((li64MbCheck - lpMbCheck->m_oCreateTime) > DEF_SECOND*5)
// {
// delete lpMbCheck;
// lpMbCheck = NULL;
// liIter = m_oGMemberCheckMap.erase(liIter);
// continue;
// }
// }
// else
// {
// liIter = m_oGMemberCheckMap.erase(liIter);
// continue;
// }
// liIter++;
// }
// m_oGMemberCheckMapLock.unlock();
}
// 执行基本属性批量插入
Sleep(1000);
}
}
// 批量插入或更新群成员信息
BOOL CIMGroupMemberCache::ChangeGroupMemberBatch(SInt64 ai64GroupID, SInt64 ai64UID,SInt16 ai16UserIdentity,
SInt64 ali64CreateDateTime,SInt8 ai8ChangeType)
{
if (ai64GroupID > 0)
{
S_GroupMember* lpMember = new S_GroupMember();
if (lpMember)
{
lpMember->m_i64GroupID = ai64GroupID;
lpMember->m_i64UID = ai64UID;
lpMember->m_i16UserIdentity = ai16UserIdentity;
lpMember->m_li64CreateDateTime = ali64CreateDateTime;
lpMember->m_i8ChangeType = ai8ChangeType;
m_oGroupMemberChangeMapLock.lock();
std::map<SInt64, std::vector<S_GroupMember*>* >::iterator liIter;
std::vector<S_GroupMember*>* lpMemberArray = NULL;
if((liIter = m_oGroupMemberChangeMap.find (ai64GroupID)) != m_oGroupMemberChangeMap.end())
lpMemberArray = liIter->second;
else
{
lpMemberArray = new std::vector<S_GroupMember*>();
if (lpMemberArray)
m_oGroupMemberChangeMap.insert(std::make_pair(ai64GroupID, lpMemberArray));
}
if (lpMemberArray)
lpMemberArray->push_back(lpMember);
m_oGroupMemberChangeMapLock.unlock();
}
}
return TRUE;
}
BOOL CIMGroupMemberCache::ChangeGroupMemberBatch(void)
{
std::vector<S_GroupMember*>* lpMemberArray = NULL;
std::map<SInt64, std::vector<S_GroupMember*>* >::iterator liIter;
m_oGroupMemberChangeMapLock.lock();
liIter = m_oGroupMemberChangeMap.begin();
while (liIter != m_oGroupMemberChangeMap.end())
{
if (( liIter->second) && (liIter->second->size() > 0 ))
{
ChangeGroupMemberBatch(liIter->second);
++liIter;
continue;
}
liIter = m_oGroupMemberChangeMap.erase(liIter);
}
m_oGroupMemberChangeMapLock.unlock();
return TRUE;
}
BOOL CIMGroupMemberCache::ChangeGroupMemberBatch(std::vector<S_GroupMember*>* apMemberArray)
{
SInt64 li64TimeBeg = CPubfuncs::GetCurTime();
int liRecourdCnt = apMemberArray->size();
BOOL lbResult = FALSE;
SInt16 ai16Result =0;
AutoDbWriterPtr lpDbWriter(m_pImGroupDbCache);
if (lpDbWriter.IsAvailable())
{
// 成员表
std::string lstrMemberTb("replace into t_group_member(p_group_id, p_group_member_id, p_group_member_identity, p_group_member_join_datetime) values");
char lszMemberTbValues[256] = {0};
std::string lstrMemberTbTemp(lstrMemberTb);
// 成员变化表
std::string lstrMemberChangeTb("replace into t_group_member_change(p_group_change_type, p_group_id, p_group_member_id , p_group_member_identity, p_group_member_join_datetime, p_group_member_change_datetime) values");
char lszMemberChangeTbValues[256] = {0};
std::string lstrMemberChangeTbTemp(lstrMemberChangeTb);
BOOL lbIsInsertChange = FALSE;
S_GroupMember* lpMember = NULL;
std::vector<S_GroupMember*>::iterator liIter;
SLong llRecortCnt = 0;
for (liIter = apMemberArray->begin(); liIter != apMemberArray->end(); ++liIter)
{
if (lpMember = *liIter)
{
if ((lpMember->m_i8ChangeType == MySql_Add) || (lpMember->m_i8ChangeType == MySql_Update))
{
// 基础表插入
sprintf_s( lszMemberTbValues, "(%I64d, %I64d, %d, %I64d),",
lpMember->m_i64GroupID,
lpMember->m_i64UID,
lpMember->m_i16UserIdentity,
lpMember->m_li64CreateDateTime);
lstrMemberTbTemp += lszMemberTbValues;
lbIsInsertChange = TRUE;
}
memset(lszMemberTbValues, 0, sizeof(char)*256);
// 变化表插入
sprintf_s( lszMemberChangeTbValues, "(%d, %I64d, %I64d, %d, %I64d, %I64d),",
lpMember->m_i8ChangeType,
lpMember->m_i64GroupID,
lpMember->m_i64UID,
lpMember->m_i16UserIdentity,
lpMember->m_li64CreateDateTime,
lpMember->m_li64ChangeDateTime);
lstrMemberChangeTbTemp += lszMemberChangeTbValues;
memset(lszMemberChangeTbValues, 0, sizeof(char)*256);
llRecortCnt++;
if (llRecortCnt >= 2000)
{
llRecortCnt = 0;
UInt64 liAffectRows = 0;
if (lbIsInsertChange)
{
lstrMemberTbTemp [lstrMemberTbTemp.size()-1] = ';';
if(0 != lpDbWriter->SqlExecuted(lstrMemberTbTemp, liAffectRows))
{NOTICE_LOG("NOTICE: CIMGroupMemberCache::ChangeGroupMemberBatch lstrMemberTbTemp false!");}
}
lstrMemberTbTemp = lstrMemberTb;
lstrMemberChangeTbTemp [lstrMemberChangeTbTemp.size()-1] = ';';
if(0 != lpDbWriter->SqlExecuted(lstrMemberChangeTbTemp, liAffectRows))
{NOTICE_LOG("NOTICE: CIMGroupMemberCache::ChangeGroupMemberBatch lstrMemberChangeTbTemp false!");}
lstrMemberChangeTbTemp = lstrMemberChangeTb;
lbIsInsertChange = FALSE;
}
delete lpMember;
}
}
if (llRecortCnt > 0)
{
UInt64 liAffectRows = 0;
if (lbIsInsertChange)
{
lstrMemberTbTemp [lstrMemberTbTemp.size()-1] = ';';
if(0 != lpDbWriter->SqlExecuted(lstrMemberTbTemp, liAffectRows))
{NOTICE_LOG("NOTICE: CIMGroupMemberCache::ChangeGroupMemberBatch lstrMemberTbTemp false!");}
}
lstrMemberChangeTbTemp [lstrMemberChangeTbTemp.size()-1] = ';';
if(0 != lpDbWriter->SqlExecuted(lstrMemberChangeTbTemp, liAffectRows))
{NOTICE_LOG("NOTICE: CIMGroupMemberCache::ChangeGroupMemberBatch lstrMemberChangeTbTemp false!");}
}
apMemberArray->clear();
}
li64TimeBeg = (CPubfuncs::GetCurTime() - li64TimeBeg);
INFO_LOG("INFO: CIMGroupMemberCache::ChangeGroupMemberBatch 插入记录数:%d, 耗时:%d", liRecourdCnt, li64TimeBeg);
return lbResult;
}
S_GroupInfo* CIMGroupMemberCache::GetGroupInfo(SInt64 aiGroupID)
{
std::map<SInt64, S_GroupInfo*>::iterator liIner;
S_GroupInfo* lpGroupInfo = NULL;
m_oGroupMemberInfoMapLock.lock();
if ((liIner = m_oGroupMemberInfoMap.find(aiGroupID)) != m_oGroupMemberInfoMap.end())
{
lpGroupInfo = liIner->second;
}
else
{
lpGroupInfo = new S_GroupInfo();
if (lpGroupInfo)
{
m_oGroupMemberInfoMap.insert(std::make_pair(aiGroupID, lpGroupInfo));
lpGroupInfo->m_i64GroupID = aiGroupID;
lpGroupInfo->m_i64LastActive = CPubfuncs::GetCurTime();
AutoDbReaderPtr lpDbReader(m_pImGroupDbCache);
if (lpDbReader.IsAvailable())
{
S_GroupMember* lpMember = NULL;
S_GroupMemberBsCard* lpMemberBsCard = NULL;
std::vector<S_GroupMember*> loMembersVct;
std::map<SInt64, S_GroupMemberBsCard*>::iterator liIter;
std::map<SInt64, S_GroupMemberBsCard*> loMembersBsCardMap;
lpDbReader->GetGroupMemberByGroupID(aiGroupID , loMembersVct);
lpDbReader->GetGroupMemberBsCardByGroupID(aiGroupID, loMembersBsCardMap);
// 群组成员信息
if (loMembersVct.size() > 0)
{
std::vector<S_GroupMember*>::iterator liVecIter;
for (liVecIter = loMembersVct.begin(); liVecIter != loMembersVct.end(); ++liVecIter)
{
if (lpMember = *liVecIter)
{
if(loMembersBsCardMap.end() != (liIter = loMembersBsCardMap.find(lpMember->m_i64UID)))
{
if (lpMemberBsCard = liIter->second)
lpMember->m_pMemberBsCard = lpMemberBsCard;
loMembersBsCardMap.erase(liIter);
}
lpGroupInfo->m_oGroupMember.insert(std::make_pair( lpMember->m_i64UID,(*liVecIter)));
if ((*liVecIter)->m_i16UserIdentity == 0)
lpGroupInfo->m_i64GroupMaster = (*liVecIter)->m_i64UID;
else if ((*liVecIter)->m_i16UserIdentity == 1)
lpGroupInfo->m_oGroupManager.insert(std::make_pair( lpMember->m_i64UID,(*liVecIter)));
}
}
}
// 清空多余的名片
if (loMembersBsCardMap.size() > 0)
{
NOTICE_LOG("NOTICE: CIMGroupMemberCache::GetGroupInfo 出现成员与成员名片不匹配的现象! GID:%I64d",aiGroupID);
for (liIter = loMembersBsCardMap.begin(); liIter != loMembersBsCardMap.end(); ++liIter)
if (lpMemberBsCard = liIter->second) delete lpMemberBsCard;
loMembersBsCardMap.clear();
}
}
}
}
m_oGroupMemberInfoMapLock.unlock();
return lpGroupInfo;
}
S_GroupMember* CIMGroupMemberCache::GetGroupMember(SInt64 ai64UserID, SInt64 aiGroupID)
{
m_oGroupMemberInfoMapLock.lock();
S_GroupMember* lpMember = NULL;
S_GroupInfo* lpGroupInfo = GetGroupInfo(aiGroupID);
std::map<SInt64, S_GroupMember*>::iterator liIter;
// 查询到群成员
if ( ( liIter = lpGroupInfo->m_oGroupMember.find(ai64UserID)) != lpGroupInfo->m_oGroupMember.end())
{
lpMember = liIter->second;
}
m_oGroupMemberInfoMapLock.unlock();
return lpMember;
}
// 添加检查成员
BOOL CIMGroupMemberCache::AddCheckMember(SInt64 aiUserID, sockaddr_in* apAddr)
{
BOOL lbResult = FALSE;
if (!apAddr)
{
NOTICE_LOG("NOTICE: 错误的地址信息 !");
return lbResult;
}
S_GroupMbCheck* lpMbCheck = NULL;
std::map<SInt64, S_GroupMbCheck*>::iterator liIter;
m_oGMemberCheckMapLock.lock();
liIter = m_oGMemberCheckMap.find(aiUserID);
if ( liIter != m_oGMemberCheckMap.end())
{
if (NULL == (lpMbCheck = liIter->second))
m_oGMemberCheckMap.erase(liIter);
}
else
{
lpMbCheck = new S_GroupMbCheck();
if (lpMbCheck)
m_oGMemberCheckMap.insert(std::make_pair(aiUserID , lpMbCheck));
}
if (lpMbCheck)
{
lpMbCheck->m_i64UidID = aiUserID;
lpMbCheck->m_oCreateTime = CPubfuncs::GetCurTime();
memset(&lpMbCheck->m_oUserAddr, 0 , sizeof(lpMbCheck->m_oUserAddr));
memcpy(&lpMbCheck->m_oUserAddr, apAddr, sizeof(lpMbCheck->m_oUserAddr));
lbResult = TRUE;
}
m_oGMemberCheckMapLock.unlock();
return lbResult;
}
// 读取检查成员
sockaddr_in CIMGroupMemberCache::GetCheckMemberAddr(SInt64 aiUserID, sockaddr_in& aoSAddr)
{
S_GroupMbCheck* lpMbCheck = NULL;
std::map<SInt64, S_GroupMbCheck*>::iterator liIter;
m_oGMemberCheckMapLock.lock();
liIter = m_oGMemberCheckMap.find(aiUserID);
if ( liIter != m_oGMemberCheckMap.end())
lpMbCheck = liIter->second;
if (lpMbCheck)
{
memset(&aoSAddr, 0 , sizeof(aoSAddr));
memcpy(&aoSAddr, &lpMbCheck->m_oUserAddr, sizeof(aoSAddr));
}
m_oGMemberCheckMapLock.unlock();
return aoSAddr;
}
// 为成员增加地址信息
void CIMGroupMemberCache::AddMemberAddr(SInt64 aiUserID, sockaddr_in& aoSAddr)
{
sockaddr_in* lpAddr = NULL;
std::map<SInt64, sockaddr_in*>::iterator liIter;
m_oGMemberAddrMapLock.lock();
liIter = m_oGMemberAddrMap.find(aiUserID);
if (liIter != m_oGMemberAddrMap.end())
{
if (NULL == (lpAddr = liIter->second))
m_oGMemberAddrMap.erase(liIter);
}
else
{
lpAddr = new sockaddr_in();
if (lpAddr) m_oGMemberAddrMap.insert(std::make_pair(aiUserID, lpAddr));
}
if (lpAddr)
{
memset(lpAddr, 0, sizeof(sockaddr_in));
memcpy(lpAddr, &aoSAddr, sizeof(aoSAddr));
}
m_oGMemberAddrMapLock.unlock();
}
// 获取群成员地址信息
sockaddr_in* CIMGroupMemberCache::GetMemberAddr(SInt64 aiUserID)
{
sockaddr_in* lpAddr = NULL;
std::map<SInt64, sockaddr_in*>::iterator liIter;
m_oGMemberAddrMapLock.lock();
liIter = m_oGMemberAddrMap.find(aiUserID);
if (liIter != m_oGMemberAddrMap.end())
{
if (NULL == (lpAddr = liIter->second))
m_oGMemberAddrMap.erase(liIter);
}
m_oGMemberAddrMapLock.unlock();
return lpAddr;
}
// 批量插入或更新群名片信息
BOOL CIMGroupMemberCache::ChangeGroupMbBsCardBatch(SInt64 ai64GroupID, SInt64 ai64UID, Byte abySex, char* apName,
char* apTelNum, char* apEmail, char* apReMarks, SInt8 ai8ChangeType)
{
if (ai64GroupID > 0)
{
S_GroupMemberBsCard* lpMemberBsCard = new S_GroupMemberBsCard();
if (lpMemberBsCard)
{
lpMemberBsCard->m_i64GroupID = ai64GroupID;
lpMemberBsCard->m_i64UID = ai64UID;
lpMemberBsCard->m_i8ChangeType = ai8ChangeType;
lpMemberBsCard->m_i64ChangeDateTime = CPubfuncs::GetCurTime();
int liLen = strlen(apName);
lpMemberBsCard->m_pName = new char[liLen+1];
if (lpMemberBsCard->m_pName)
{
memset(lpMemberBsCard->m_pName, 0 , sizeof(char)*(liLen+1));
memcpy(lpMemberBsCard->m_pName, apName, sizeof(char)*liLen);
}
liLen = strlen(apTelNum);
lpMemberBsCard->m_pTelNum = new char[liLen+1];
if (lpMemberBsCard->m_pTelNum)
{
memset(lpMemberBsCard->m_pTelNum, 0 , sizeof(char)*(liLen+1));
memcpy(lpMemberBsCard->m_pTelNum, apTelNum, sizeof(char)*liLen);
}
liLen = strlen(apEmail);
lpMemberBsCard->m_pEmail = new char[liLen+1];
if (lpMemberBsCard->m_pEmail)
{
memset(lpMemberBsCard->m_pEmail, 0 , sizeof(char)*(liLen+1));
memcpy(lpMemberBsCard->m_pEmail, apEmail, sizeof(char)*liLen);
}
liLen = strlen(apReMarks);
lpMemberBsCard->m_pReMarks = new char[liLen+1];
if (lpMemberBsCard->m_pReMarks)
{
memset(lpMemberBsCard->m_pReMarks, 0 , sizeof(char)*(liLen+1));
memcpy(lpMemberBsCard->m_pReMarks, apReMarks, sizeof(char)*liLen);
}
m_oGroupMbBsCardChangeMapLock.lock();
std::map<SInt64, std::vector<S_GroupMemberBsCard*>* >::iterator liIter;
std::vector<S_GroupMemberBsCard*>* lpMemberBsCardArray = NULL;
if((liIter = m_oGroupMbBsCardChangeMap.find (ai64GroupID)) != m_oGroupMbBsCardChangeMap.end())
lpMemberBsCardArray = liIter->second;
else
{
lpMemberBsCardArray = new std::vector<S_GroupMemberBsCard*>();
if (lpMemberBsCardArray)
{m_oGroupMbBsCardChangeMap.insert(std::make_pair( (ai64GroupID), lpMemberBsCardArray));}
}
if (lpMemberBsCardArray)
lpMemberBsCardArray->push_back(lpMemberBsCard);
m_oGroupMbBsCardChangeMapLock.unlock();
}
}
return TRUE;
}
BOOL CIMGroupMemberCache::ChangeGroupMbBsCardBatch(void)
{
std::vector<S_GroupMemberBsCard*>* lpMemberArray = NULL;
std::map<SInt64, std::vector<S_GroupMemberBsCard*>* >::iterator liIter;
m_oGroupMbBsCardChangeMapLock.lock();
liIter = m_oGroupMbBsCardChangeMap.begin();
while (liIter != m_oGroupMbBsCardChangeMap.end())
{
if (( liIter->second) && (liIter->second->size() > 0 ))
{
ChangeGroupMbBsCardBatch(liIter->second);
++liIter;
continue;
}
liIter = m_oGroupMbBsCardChangeMap.erase(liIter);
}
m_oGroupMbBsCardChangeMapLock.unlock();
return TRUE;
}
BOOL CIMGroupMemberCache::ChangeGroupMbBsCardBatch(std::vector<S_GroupMemberBsCard*>* apMbBsCardArray)
{
SInt64 li64TimeBeg = CPubfuncs::GetCurTime();
int liRecourdCnt = apMbBsCardArray->size();
BOOL lbResult = FALSE;
SInt16 ai16Result =0;
AutoDbWriterPtr lpDbWriter(m_pImGroupDbCache);
if (lpDbWriter.IsAvailable())
{
BOOL lbIsInsertChange = FALSE;
// 成员表
std::string lstrMemberBsCardTb("replace into t_group_member_bscard(p_group_id, p_group_member_id, p_group_member_dname, p_group_member_sex, p_group_member_telno, p_group_member_email, p_group_member_remarks) values");
char lstrMemberBsCardValues[2000] = {0};
std::string lstrMemberBsCardTbTemp(lstrMemberBsCardTb);
// 成员变化表
std::string lstrMemberChangeTb("replace into t_group_member_bscard_change(p_group_change_type, p_group_id, p_group_member_id, p_group_member_dname, p_group_member_sex, p_group_member_telno, p_group_member_email, p_group_member_remarks, p_group_member_change_datetime) values");
char lszMemberChangeTbValues[2000] = {0};
std::string lstrMemberChangeTbTemp(lstrMemberChangeTb);
S_GroupMemberBsCard* lpMemberBsCard = NULL;
std::vector<S_GroupMemberBsCard*>::iterator liIter;
SLong llRecortCnt = 0;
for (liIter = apMbBsCardArray->begin(); liIter != apMbBsCardArray->end(); ++liIter)
{
if (lpMemberBsCard = *liIter)
{
if ((lpMemberBsCard->m_i8ChangeType == MySql_Add) || (lpMemberBsCard->m_i8ChangeType == MySql_Update))
{
// 基础表插入
sprintf_s( lstrMemberBsCardValues, "(%I64d, %I64d, '%s', %d,'%s','%s','%s'),",
lpMemberBsCard->m_i64GroupID,
lpMemberBsCard->m_i64UID,
lpMemberBsCard->m_pName,
lpMemberBsCard->m_bySex,
lpMemberBsCard->m_pTelNum,
lpMemberBsCard->m_pEmail,
lpMemberBsCard->m_pReMarks);
lstrMemberBsCardTbTemp += lstrMemberBsCardValues;
lbIsInsertChange = TRUE;
}
memset(lstrMemberBsCardValues, 0, sizeof(char)*2000);
// 变化表插入
sprintf_s( lszMemberChangeTbValues, "(%d,%I64d, %I64d, '%s', %d,'%s','%s','%s',%I64d),",
lpMemberBsCard->m_i8ChangeType,
lpMemberBsCard->m_i64GroupID,
lpMemberBsCard->m_i64UID,
lpMemberBsCard->m_pName,
lpMemberBsCard->m_bySex,
lpMemberBsCard->m_pTelNum,
lpMemberBsCard->m_pEmail,
lpMemberBsCard->m_pReMarks,
lpMemberBsCard->m_i64ChangeDateTime);
lstrMemberChangeTbTemp += lszMemberChangeTbValues;
memset(lszMemberChangeTbValues, 0, sizeof(char)*2000);
llRecortCnt++;
if (llRecortCnt >= 2000)
{
llRecortCnt = 0;
UInt64 liAffectRows = 0;
if (lbIsInsertChange)
{
lstrMemberBsCardTbTemp [lstrMemberBsCardTbTemp.size()-1] = ';';
if(0 != lpDbWriter->SqlExecuted(lstrMemberBsCardTbTemp, liAffectRows))
{NOTICE_LOG("NOTICE: CIMGroupMemberCache::ChangeGroupMbBsCardBatch lstrMemberBsCardTbTemp false!");}
}
lstrMemberBsCardTbTemp = lstrMemberBsCardTb;
lstrMemberChangeTbTemp [lstrMemberChangeTbTemp.size()-1] = ';';
if(0 != lpDbWriter->SqlExecuted(lstrMemberChangeTbTemp, liAffectRows))
{NOTICE_LOG("NOTICE: CIMGroupMemberCache::ChangeGroupMbBsCardBatch lstrMemberChangeTbTemp false!");}
lstrMemberChangeTbTemp = lstrMemberChangeTb;
lbIsInsertChange = FALSE;
}
delete lpMemberBsCard;
}
}
if (llRecortCnt > 0)
{
UInt64 liAffectRows = 0;
if (lbIsInsertChange)
{
lstrMemberBsCardTbTemp [lstrMemberBsCardTbTemp.size()-1] = ';';
if(0 != lpDbWriter->SqlExecuted(lstrMemberBsCardTbTemp, liAffectRows))
{NOTICE_LOG("NOTICE: CIMGroupMemberCache::ChangeGroupMbBsCardBatch lstrMemberBsCardTemp false!");}
}
lstrMemberChangeTbTemp [lstrMemberChangeTbTemp.size()-1] = ';';
if(0 != lpDbWriter->SqlExecuted(lstrMemberChangeTbTemp, liAffectRows))
{NOTICE_LOG("NOTICE: CIMGroupMemberCache::ChangeGroupMbBsCardBatch lstrMemberChangeTbTemp false!");}
}
apMbBsCardArray->clear();
}
li64TimeBeg = (CPubfuncs::GetCurTime() - li64TimeBeg);
INFO_LOG("INFO: CIMGroupMemberCache::ChangeGroupMbBsCardBatch 插入记录数:%d, 耗时:%d", liRecourdCnt, li64TimeBeg);
return lbResult;
}
// 群组成员信息变化最大值读取
BOOL CIMGroupMemberCache::GetGroupMemberChangeLast(SInt64& ai64LastID)
{
BOOL lbResult = FALSE;
SInt64 liBegTime = CPubfuncs::GetCurTime();
AutoDbReaderPtr lpDbReader(m_pImGroupDbCache);
if (lpDbReader.IsAvailable())
{
if(0 == lpDbReader->GetGroupMemberChangeLast(ai64LastID))
{
INFO_LOG("INFO: 读取群组动态信息变化最大值 值:[%I64d] 耗时:[%I64d]", ai64LastID, (CPubfuncs::GetCurTime() - liBegTime));
lbResult = TRUE;
}
}
return lbResult;
}
// 群组成员名片变化最大值读取
BOOL CIMGroupMemberCache::GetGroupMbBscardChangeLast(SInt64& ai64LastID)
{
BOOL lbResult = FALSE;
SInt64 liBegTime = CPubfuncs::GetCurTime();
AutoDbReaderPtr lpDbReader(m_pImGroupDbCache);
if (lpDbReader.IsAvailable())
{
if(0 == lpDbReader->GetGroupMbBscardChangeLast(ai64LastID))
{
INFO_LOG("INFO: 读取群组动态信息变化最大值 值:[%I64d] 耗时:[%I64d]", ai64LastID, (CPubfuncs::GetCurTime() - liBegTime));
lbResult = TRUE;
}
}
return lbResult;
}