/*
	File:		CDBBaseObject.10.1.h

	Contains:	C++ base class definition for persistent database objects

	Copyright:	© 2003 by Apple Computer, Inc., all rights reserved.

 	NOT_FOR_OPEN_SOURCE <to be reevaluated at a later time>

	Change History:
*/


#ifndef __CDBBaseObject_10_1_h__
#define __CDBBaseObject_10_1_h__	1

#include "CBaseDatabase.10.1.h"
#include "UException.h"


typedef struct
{
	OSType 	fSignature;
	uInt32 	fVersion;
	uInt32 	fSize;			// zero value indicates that object is variable length on disk
} StdDBObjHeader_10_1;

typedef struct
{
	OSType	fSignature;
} StdDBObjFooter_10_1;

// CDBObject Constants
const uInt32 kDBObjectHeaderLength_10_1 = (sizeof (StdDBObjHeader_10_1));
const uInt32 kDBObjectFooterLength_10_1 = (sizeof (StdDBObjFooter_10_1));

const long	 kReallyBigMemSize_10_1		= 0x7fffffff;
const uInt32 kDefaultTime2Wait_10_1		= 45;	// time expressed in ticks, wait 3/4 of a second..
const uInt32 kCacheHashTableSize_10_1	= 29;
const uInt32 kAllListFlushValue_10_1 	= 0xffffffff;
const uInt32 kBaseSecondsPerMin_10_1	= 60;
const uInt32 kBaseMilliSecsPerSec_10_1	= 1000;
const uInt32 kSafetyWaitTime_10_1		= 2 * kBaseSecondsPerMin_10_1 * kBaseMilliSecsPerSec_10_1;


class CSmartTimer_10_1
{
public:
					CSmartTimer_10_1 ( uInt32 inTime2Wait = kDefaultTime2Wait_10_1 );
	virtual		   ~CSmartTimer_10_1 ( void );

	virtual	void	ResetTimer	( uInt32 inTime2Wait = kDefaultTime2Wait_10_1 );
	virtual	Boolean	KeepWaiting	( void );

private:
	uInt32	fStartTime;
	uInt32	fTime2Wait;
	uInt32	fCount;
}; // CSmartTimer_10_1

class CDBBaseObject_10_1;
typedef CDBBaseObject_10_1*	(*ObjAllocFuncPtr_10_1)(void);	// return false if there is no data....

class CDBBaseObject_10_1
{
public:
			CDBBaseObject_10_1		( 	StdDBObjHeader_10_1		*inObjHeader,
									StdDBObjFooter_10_1		*inObjFooter,
									void				*inObjData,
									const OSType		inObjSignature,
									const uInt32		inObjVersion,
									const uInt32		inObjSize 		);
	virtual	~CDBBaseObject_10_1		( void );
	
	virtual CDBBaseObject_10_1*	Use			( CBaseDatabase_10_1	*inBaseDB );
	virtual void 			ChkCompilerStructAlignment	( void );
			void			Done		( CDBBaseObject_10_1* &inPtr );	// do _NOT_ make this virtual!!!!

	static	CDBBaseObject_10_1*	UniversalFindByID	( CBaseDatabase_10_1	*inBaseDB,
													const ObjID				inObjID,
													const OSType			inObjType,
													const uInt32			inObjVersion,
													const uInt32			inObjSize,
													ObjAllocFuncPtr_10_1	inObjAllocFuncPtr	);

	virtual CBaseDatabase_10_1	*GetOwnerDBPtr			( void );												
	virtual	ObjID			GetObjectID				( void ) = 0;
	virtual	void*			GetObjectData			( void );

	virtual	OSType			GetObjectType			( void );
	virtual	uInt32			GetObjectVersion		( void );
	virtual uInt32			GetObjectSize			( void );

	virtual	void			SetNextPtr				( CDBBaseObject_10_1 *inObject );
	virtual CDBBaseObject_10_1*	GetNextPtr				( void );

	virtual	void			SetPrevPtr				( CDBBaseObject_10_1 *inObject );
	virtual CDBBaseObject_10_1*	GetPrevPtr				( void );
	
	virtual	uInt32			GetObjectRefCount		( void );
	virtual void			SetObjectRefCount		( const uInt32 inObjectRefCount );

	virtual void			AddObjectReference		( void );
	virtual void			RemoveObjectReference	( void );
	
	virtual	void			setDirty				( const Boolean inForceWriteFlag = false );
	virtual	Boolean			GetDirtyFlag			( void );
	virtual	void			SetDirtyFlag			( const Boolean inDirtyFlag );
	
	virtual OSErr			WriteObject				( void );

	// Thread OwnerShip
	virtual	ExceptionCode	GetObjectLock			( const Boolean inWaitForObjectLock, const uInt32 inMaxWaitTime = kSafetyWaitTime_10_1 );
	virtual	void			ReleaseObjectLock		( const Boolean inNotifyOtherThreadsFlag );
	virtual	void			WakeUpObjectThreads		( void );

private:
	volatile CBaseDatabase_10_1	*fOwnerDBPtr;
	volatile uInt32				fRefCount;
	volatile CDBBaseObject_10_1	*fNextPtr;
	volatile CDBBaseObject_10_1	*fPrevPtr;
	volatile Boolean			fDirty;

	StdDBObjHeader_10_1			*fObjHeader;
	StdDBObjFooter_10_1			*fObjFooter;
	void						*fObjData;

}; //  class CDBBaseObject_10_1


class CDBBaseObjectCacheList_10_1
{
public:
			 CDBBaseObjectCacheList_10_1	();
	virtual ~CDBBaseObjectCacheList_10_1	();
	
	virtual	CDBBaseObject_10_1*	AddObject	( CDBBaseObject_10_1 *inObject );
	virtual	Boolean			RemoveObject	( CDBBaseObject_10_1 *inObject );
	
	virtual	uInt32			GetListCount	( void );
	virtual	void			SetListCount	( const uInt32 inListCount );
	
	virtual	uInt32			GetListMax		( void );
	virtual	void			SetListMax		( const uInt32 inListCount );
	
	virtual	CDBBaseObject_10_1*	GetListHead	( void );
	virtual	void			SetListHead		( CDBBaseObject_10_1* inObject );
	
	virtual	CDBBaseObject_10_1*	FindObject	( const ObjID inObjectID );
	
	virtual	void			FlushList		( const Boolean inWakeupThreads );
	
	virtual void			DoListLock		( void );
	virtual void			DoListRelease	( void );

private:
	volatile CDBBaseObject_10_1	*fListHead;
	volatile uInt32			fListCount;
	volatile uInt32			fListMaxCount;

}; // class CDBBaseObjectCacheList_10_1

class TypeToIndexMapping_10_1
{
public:
	OSType					 fObjType;
	uInt32					 fCacheListIndex;
	TypeToIndexMapping_10_1 *fNextPtr;
}; // class TypeToIndexMapping

class CDBBaseObjectCache_10_1
{
public:
			 CDBBaseObjectCache_10_1( CBaseDatabase_10_1 *inObject );
	virtual	~CDBBaseObjectCache_10_1();
	
	virtual void			SetBaseDBPtr		( CBaseDatabase_10_1 *inObject );
	virtual CBaseDatabase_10_1*	GetBaseDBPtr		( void );
	
	virtual	CDBBaseObject_10_1*	Search4Object		( const ObjID inObjectID );
	virtual	CDBBaseObject_10_1*	Search4Object		( const OSType inObjectType, const ObjID  inObjectID );
	virtual	CDBBaseObject_10_1*	AddObject2List		( CDBBaseObject_10_1 *inObject );
	virtual	Boolean			RemoveObjFromList	( CDBBaseObject_10_1 *inObject );
	
	virtual	void			LockTheCache		( const OSType inObjectType );
	virtual	void			UnLockTheCache		( const OSType inObjectType );

	virtual	void			FlushAllList		( const Boolean inWakeupThreads );
	virtual	void			FlushList			( const OSType inObjectType, const Boolean inWakeupThreads );
	virtual	uInt32			CalcObjectCount		( void );

	virtual	void			Wait				( const uInt32 inIndex );
	virtual	void			Signal				( const uInt32 inIndex );
	
	virtual	CDBBaseObject_10_1*	AddObject			( CDBBaseObject_10_1 *inObject );
	virtual	Boolean			RemoveObject		( CDBBaseObject_10_1 *inObject );
	virtual	CDBBaseObject_10_1*	FindObject			( const ObjID	inObjectID );
	virtual CDBBaseObject_10_1*	FindObject			( const OSType	inObjectType, const ObjID	inObjectID );
	virtual	uInt32			GetListCount		( void );
	virtual uInt32			CalcCacheObjCount	( void );
	virtual	void			Flush				( const OSType inObjectType, const Boolean inWakeupThreads );
											
	virtual	uInt32			DoListHash			( const OSType inObjecttype, const ObjID  inObjectID );

protected:
	virtual void			SetUpHashTable		( void );
	
	CBaseDatabase_10_1 				*fBaseDBPtr;
	uInt32						fCacheListCount;

private:
	TypeToIndexMapping_10_1		   *fHashTable[ kCacheHashTableSize_10_1 ];
	CDBBaseObjectCacheList_10_1	   *fCacheList;

}; // CDBBaseObjectCache_10_1


#endif // __CDBBaseObject_h__
