IM 开源项目 群组服务 缓存设计实现之 成员属性

时序:

接上文,不啰嗦了。

【定义】:

 

/* 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;
}


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值