/*
*	replication.h (wb)
*
*	Data structure decls and prototypes relating to the replication
*	manager
*
*  Created by: Win Bausch and Bettina Kemme
*
*/

#ifndef REPLICATION_H
#define REPLICATION_H

#include <unistd.h>
#include "libpq/bufferedSock.h"
#include "replication/writeset.h"

/* (mc) debugging defs
#define RMGR_DEBUG
#define GCMGR_DEBUG
#define DEBUG_TXN_REPL_STATE*/

/*  swu debugging defs
#define FE_DEBUG
#define EXEC_DEBUG*/

/*  swu replication statistics 
#define COLLECT_REPL_STAT*/

#define MAX_GROUP_MEMBERS 	50
/* 
 * (mc) MAX_GROUP_NAME: similar to sp.h, 
 */
#define MAX_GROUP_NAME 		32
#define HOSTID_SIZE 		4
#define SITE_CHANGE_SIZE	4
/**/
//#define ROUTING_HDR_SIZE 4
#define RMGR_HDR_SIZE 		8
#define RMGR_ID_SIZES 		8   /* 2* sizeof(uint32) */
#define BKND_ID_SIZE 		8
#define GROUPCOMM_HDR_SIZE 	RMGR_HDR_SIZE + BKND_ID_SIZE

/*  swu */
#define NewGlobalTransactionId() \
	curGlobalTxnId = curGlobalTxnId + 1;

/*
*   does this transaction perform operations on replicated data?
*       NOT_REPLICATED stands for the standard postgres txn
*       REPLICATED_LOCAL designates a txn that is replicated and runs
*           at its home site
*       REPLICATED_REMOTE designates a txn that is replicated and started
*           by the replica manager at a remote site
*   For now, full user data replication is performed
*/

typedef enum
{
	NOT_REPLICATED,
	REPLICATED_REMOTE,
	REPLICATED_LOCAL
} TransactionType;

extern TransactionType txn_type;

/*
*	supported msg types
*/
typedef enum
{
	MSG_OPENING,		/* 0 */
	MSG_CLOSING,
	MSG_NEW_TXN,
	MSG_WRITESET,
	MSG_WS_RECEIVED,

	/*  swu */
	MSG_CHECKED,		/* 5 */
	MSG_ABORT,
	MSG_COMMIT,

	/*MSG_LOCKED,*/
	MSG_ACK,
	MSG_READY,
	MSG_PROTO_ERROR,	/* 10 */
	MSG_INVAL,
	/* failover types */
	MSG_VIEW_CHANGE,
	MSG_MASTER_CHANGE,
	MSG_HOST_CHANGE,
	/* recovery types */
	MSG_LAST_TXN,		/* 15 */
	MSG_RECOVERY_INFO,
	MSG_TXNLIST,

	/*  swu never used? (rem)*/
	/*MSG_BKND_REC,*/
	MSG_NOMORETXNS,
	MSG_STEPACTION,
	MSG_XLOG_FAILURE,	/* 20 */	
	MSG_SITE_READY
} rc_msg_t;

/* 
* valid connection states (local and remote txn)
*/
typedef enum
{
	/* (mc) new states for the Master/Slave approach */
	L_LOCAL_STATE,
	L_SEND_STATE,
	L_IDLE_STATE,
	L_DESTROY_STATE,

	/*  swu  add */
	L_CHECK_STATE,
	R_IDLE_STATE,
	R_CHECK_STATE,

	R_FREE_STATE,
	R_BUSY_STATE,
	
	S_RECOVERY_STATE,
	
	READ_ONLY,	/* read only txn */
	/*	(mc) no more needed in a Master/Slave approach
	CLOSED,
	READ_PHASE,
	QUERY_PHASE,
	SEND_PHASE,
	LOCK_PHASE,
	WRITE_PHASE,
	*/
	/* COMMITTABLE,*/    /* now in result */
	/*READY_TO_CLOSE,*/   /* bk for remote backends */
	/*CLOSE_AND_DESTROY,*/  /* bk: for local backends */
	/*
	ABORTED,
	NO_BKND,
	BKND_PRESENT,
	*/
} rc_state_t;

/* (mc)  used in pg_spread */
typedef enum
{
	SITE_FAILED,
	SITE_JOINED,
	SITE_CHANGE_UNKNOWN,

	/*  swu only for master slave approach */
	SITE_BECOMES_MASTER,
	SITE_BECOMES_SLAVE
} siteViewChangeType;
/**/

/* bk
*  local process connects once (when first write set is sent)
*  and then reuses connection
*/
typedef enum
{
  NOT_YET_CONNECTED,
  CONNECTED
} rc_connection_t;


/* bk (mc) no more needed in a Master/Slave approach
*  add result, determined by the the msg_commit/msg_abort

typedef enum
{
  UNKNOWN_RESULT,
  COMMITTABLE,
  TO_ABORT
} rc_result_t;
*/

/*
*	message receiving states
*/
typedef enum
{
	RECV_IDLE,
	RECV_HDR,
	RECV_DATA,
} recv_state_t;

/*
*	routing targets (src and dest)
*
*	ATTN: order is important, as these values 
*		are used as indexes into an array!!!!
*/
typedef enum
{
	LOCAL_ADDR,		
	REMOTE,
	GROUPCOMM,
	INVAL,
} route_addr_t;


/* (mc)
 *   
 */
typedef enum Rconn_type
{
	RCONN_LOCAL,
	RCONN_REMOTE_REPLICATION,
	RCONN_REMOTE_RECOVERY,
	RCONN_RECOVERINGSITE,
	RCONN_PEERSITE,
	RCONN_UNKNOWN
} Rconn_type;


/*
*	struct used in message receiving process
*	bsock - buffered socket
*	recv_state - contains state info about which part of
*			a message we are receiving (header or body)
*	datalen - length of the data chunk we wait for
*
*	see RmgrReceive in replicaManager.c for an example of its use	
*/
typedef struct
{
	bufsockptr		bsock;
	recv_state_t 	recv_state;
	int 			datalen;
} DataConn;

/*
*	Rmgr uses this struct to manage a backend
*	that connected to send its write set
*
*	dc - message interface to the backend
*	state - the state of the connection
*	result - the decision message for this transaction
*	         (commit, abort, unknown)
*	pid - the PID of the backend (local backends only)
*	hostid - the hostid associated with the txn
*	xid - the xid associated with the txn
*	numDelivered - number of messages that have been delivered,
*                  determines if any msgs in transit
*	
*	NOTE: hostid and xid are used as key to	identify the
*	      backends belonging to	a replicated txn. In other
*	      words, a local transaction and all its remote	txns
*	      carry the same key: the xid of the local txn plus
*	      the host id of the machine where the local txn runs
*/
typedef struct
{
	DataConn		dc;	
	rc_state_t		state;
	/* (mc) no more needed in a Master/Slave approach
	rc_result_t		result;
	int				numDelivered;
	*/
	int				pid;
	/* remote backends can be two types (mc)*/
	Rconn_type		rbkndtype;
	uint32			hostid;
	uint32			xid;

	/*  swu ( rem) */
	/* # ws sent but not delivered yest 
#ifdef REPL_UPDATE_EVERYWHERE
	int				numNotDelivered;	
#endif*/
} Rconn;

/*  swu */
/* the last global txn ID issued by this site */
extern TransactionId curGlobalTxnId;
extern TransactionId globalTxnId;
extern bool hasAddedToSysTable;
extern bool needUpdateSysTable;


/* for postgres.c, writeset.c */
extern void pg_exec_query(char *query_string);
#endif

