/**********************************************************************
 
	Copyright (C) 2005- Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

**********************************************************************/


#ifndef ___MATRIX_H___
#define ___MATRIX_H___

#include	"xl.h"
#include	"queue.h"
#include	"recordlist64.h"

#define NCACHE_SIZE		100
#define NHASH_SIZE		(4*NCACHE_SIZE+3)
#define MIN_NCACHE_SIZE		NCACHE_SIZE
#define STAT_LEN		2
#define STAT_TICK		11
#define NCACHE_RATE		10
#define MAX_OPEN_FILES_FOR_MX	10
#define MLOCK_LIFE_TIME		30
#define DIRTY_LIMIT		30

typedef struct matrix_sexp {
	struct matrix_sexp *	next;
	struct matrix_sexp *	prev;
	void *			data;
	void			(*gc_func)();
	unsigned		del:1;
	char *			file;
	int			line;
} MATRIX_SEXP;

#define CH_PARENT		0x80000000
#define CH_CHILDREN		0xc0000000
#define CH_ATTRIBUTE		0x40000000
#define CH_TARGET		0x00000000

#define OPT_TRUNC		1
#define OPT_CURVE		2

typedef struct matrix_data_header {
	char			offset;
	char			type;
	short			dim;
} MATRIX_DATA_HEADER;

typedef struct matrix_dh_set {
	MATRIX_DATA_HEADER * 	hd;
	struct matrix_data_type * tp;
	int *			ix;
	int			total_element;
	void *			offset;
} MATRIX_DH_SET;

typedef struct matrix_alloc_vector_param {
	int			dim;
	int *			ix_size;
	void *			default_data;
	struct mx_cache *	mxc;
} MATRIX_ALLOC_VECTOR_PARAM;

typedef struct matrix_alloc_block_param {
	MATRIX_DATA_HEADER	h;
	int			size;
	void *			block;
} MATRIX_ALLOC_BLOCK_PARAM;

#define MD_AREA(x,type)	(*(type*)(((char*)(x))+((MATRIX_DATA_HEADER*)(x)->offset)))

typedef struct matrix_list {
	struct matrix_list * 		next;
	struct matrix_node *		node;
} MATRIX_LIST;


#define MT_ACCESS_MAX		14


typedef struct matrix_access_list {
	struct matrix_access_list *	next;
	int				id;
} MATRIX_ACCESS_LIST;

typedef struct matrix_token {
	Q_HEADER			h;
	struct matrix_token *		next;
	MATRIX_ACCESS_LIST *		access_list;
	int				access_target_id;
	struct matrix *			wait_matrix;
	struct matrix_node *		wait_node;
	struct matrix_node *		process_node;
	struct matrix_list *		locked_node_list;
	XL_SEXP *			cal_target;
	void				(*func)();
	void 				(*aboat_func)();
	void *				aobat_work;
	MATRIX_SEXP *			env;

	int				loop_no;

	int				normal_jump;
	int				normal_jump_status;
	int				err_jump;
	int				err_jump_status;
	
	void *				work;

	char *				c_file;
	int				c_line;
} MATRIX_TOKEN;


#define PR_UP		0
#define PR_DOWN		1
#define PR_STRT		2
#define PR_MAX		3

#define MI_TOP		0
#define MI_MIDDLE	1
#define MI_BOTTOM	2

#define MI_DEF_TP	(0+MI_TOP)
#define MI_DEF_MD	(0+MI_MIDDLE)
#define MI_DEF_BT	(0+MI_BOTTOM)
#define MI_FETCH_1_TP	(3+MI_TOP)
#define MI_FETCH_1_MD	(3+MI_MIDDLE)
#define MI_FETCH_1_BT	(3+MI_BOTTOM)
#define MI_FETCH_2_TP	(6+MI_TOP)
#define MI_FETCH_2_MD	(6+MI_MIDDLE)
#define MI_FETCH_2_BT	(6+MI_BOTTOM)
#define MI_EDIT_1_TP	(9+MI_TOP)
#define MI_EDIT_1_MD	(9+MI_MIDDLE)
#define MI_EDIT_1_BT	(9+MI_BOTTOM)
#define MI_EDIT_2_TP	(12+MI_TOP)
#define MI_EDIT_2_MD	(12+MI_MIDDLE)
#define MI_EDIT_2_BT	(12+MI_BOTTOM)
#define MI_VISU_1_TP	(15+MI_TOP)
#define MI_VISU_1_MD	(15+MI_MIDDLE)
#define MI_VISU_1_BT	(15+MI_BOTTOM)
#define MI_VISU_2_TP	(18+MI_TOP)
#define MI_VISU_2_MD	(18+MI_MIDDLE)
#define MI_VISU_2_BT	(18+MI_BOTTOM)
#define MI_SAVE_TP	(21+MI_TOP)
#define MI_SAVE_MD	(21+MI_MIDDLE)
#define MI_SAVE_BT	(21+MI_BOTTOM)
#define MI_MAX		24



#define MI_GET(mi,n)	\
	((n)->matrix->total_levels-1 == (n)->dim_code[0] ? 	\
		((mi) - ((mi) % 3)) :				\
		((n)->dim_code[0] == 0 ?			\
			((mi) - ((mi) % 3)) + MI_BOTTOM :	\
			((mi) - ((mi) % 3)) + MI_MIDDLE))

typedef struct matrix_channel_info {
	struct matrix_data_type *	data_type;
	int				flags;
#define MF_SEND		0x00000001
#define MF_FILE		0x00000002
#define MF_VISU		0x00000004
	void *				default_data;
	INTEGER64			default_data_fofs;
} MATRIX_CHANNEL_INFO;



typedef struct matrix_channel {
	void *			data;
	INTEGER64		data_fofs;
} MATRIX_CHANNEL;

typedef struct matrix_node_header {
	struct matrix_node *	next;
	struct matrix_node *	prev;
} MATRIX_NODE_HEADER;

typedef struct matrix_node {
	struct matrix_node_header h;
	struct matrix_node *	nh_next;
	struct matrix *		matrix;

	INTEGER64 *		dim_code;

	int			status;
#define MS_NOBIND			0
#define MS_PROCESS			1
#define MS_OK				2
#define MS_LOADING_ERR_1		3
#define MS_PROCESS_ERR_1		4
#define MS_EDIT_ERR_1			5
#define MS_EDIT_ERR_2			6
	int			locked;
	int 			ch_lock;
	int			ch_lock_tid;
	unsigned		save_lock:1;
	unsigned int 		dirty_file_time;


	MATRIX_CHANNEL *	channel;
	char *			nlist_dim_bit_field;
	INTEGER64 **		nlist_dim_addr;
	int			nlist_dim_bit_field_len;
	int			nlist_dim_addr_len;

	MATRIX_TOKEN *		wait_token;
	MATRIX_TOKEN *		process_token;
	INTEGER64		req_level;
	INTEGER64		last_access;

	/* for file */

	INTEGER64		fofs;
	INTEGER64		ring_fofs;
	INTEGER64		dim_addr_fofs;
	INTEGER64		dim_addr_size;
} MATRIX_NODE;

#define MATRIX_NULLNODE		((INTEGER64)-1)

typedef struct matrix_param {
	int			channel_nos;
	int			dim;
	int			pri_area[MI_MAX];
	int			flags;
#define MPF_SET			0x80000000
#define MPF_INDEX_HEM		0x00000001
#define MPF_CACHE_FILE		0x00000002
	int			total_levels;
	INTEGER64		modify_time;
	void			(*open_method)(MATRIX_TOKEN*);
	int			(*read_file)(MATRIX_TOKEN*);
	int			(*write_file)(MATRIX_TOKEN*);
	int			(*read_net)(MATRIX_TOKEN*);
	void			(*close_file)(struct matrix *);
	void			(*close_net)(struct matrix *);
	void			(*new_token)(MATRIX_TOKEN * t,int);
	void			(*free_token)(MATRIX_TOKEN * t,int);
	void 			(*trigger)(int ttype,void * t);
#define TRT_MATRIX_STANBY	1
#define TRT_TOKEN		2
#define TRT_FINISH		3
} MATRIX_PARAM;

#define MPT_NEW_TOKEN_NODE	1
#define MPT_NEW_TOKEN_MATRIX	2

#include	"pdb64.h"
#include	"favt64.h"

typedef struct matrix {
	struct matrix *		mx_next;
	struct matrix *		mx_prev;

	int 			mode;
#define MM_CREATE		0
#define MM_STANBY		1
#define MM_ERR			2
#define MM_CLOSE		3

	MATRIX_CHANNEL_INFO *	channel_info;
	MATRIX_NODE *		node_hash[NHASH_SIZE];
	
	MATRIX_PARAM		p;

	int			total_levels;
	unsigned char *		dim_divide;
	unsigned char *		block_size;
	INTEGER64 *		pixel_size;
	INTEGER64 **		pixel_size_list;
	MATRIX_SEXP *		cal[MI_MAX];
	void *			open_work;

	L_CHAR *		neturl;
	L_CHAR *		filename;
	L_CHAR *		key;

	int			dim_bit_field;

	MATRIX_TOKEN *		wait_token;
	int			token_cnt;

	int			flags;
#define MXF_CREATE_ACCESS	0x00000001
	int			access_cnt;

	int			access_lock;
	INTEGER64		last_access;

	MATRIX_SEXP *		mx_env;

	/* for file */

	void *			file_work;

} MATRIX;


typedef struct matrix_string_buffer {
	char * 			data;
	struct matrix_string_buffer *	next;
	struct matrix_string_buffer *	tail;
	int				len;
} MATRIX_STRING_BUFFER;


typedef struct matrix_data_type {
	int			type;
#define MDT_VECTOR		0x00000010
#define MDT_SCOLOR		0x00000000
#define MDT_BASE_TYPE		0x0000000f
#define MDT_BIT			0x00000001
#define MDT_INT8		0x00000002
#define MDT_INT16		0x00000003
#define MDT_INT32		0x00000004
#define MDT_INT64		0x00000005
#define MDT_UINT8		0x00000006
#define MDT_UINT16		0x00000007
#define MDT_UINT32		0x00000008
#define MDT_UINT64		0x00000009
#define MDT_FLOAT		0x0000000a
#define MDT_DOUBLE		0x0000000b
#define MDT_RGB8		0x0000000c
#define MDT_BLOCK		0x0000000d
#define MDT_STRING		0x0000000e
#define MDT_SEXP		0x0000000f
#define MDT_MAX			0x00000020
	struct matrix_data_type * parent;
	int			(*get_size)(struct matrix_data_type*,
					void*);
	void *			(*sexp2md)(int * cpy,
					struct matrix_data_type*,
					XL_SEXP * s);
	XL_SEXP *		(*md2sexp)(struct matrix_data_type*,
					void*);
	int			(*cmp)(struct matrix_data_type*,
					void*,void*);
	void			(*copy)(struct matrix_data_type*,
					void*,void*,int,void*);
	void *			(*alloc_copy)(struct matrix_data_type*,
					void*,int,void*);
	void *			(*alloc_data)(struct matrix_data_type*,
					int,void*,
					void*,char*,int);
#define MD_TYPE_MASK	0xf
#define MD_MALLOC	1
#define MD_MMALLOC	2
#define MD_DALLOC	3
#define MD_CALLOC	4

#define MD_NOT_COPY	0x10
	void			(*free_data)(struct matrix_data_type*,
						void *);

	int			(*thinned_rep)(struct matrix_data_type *,
						struct matrix *,
						INTEGER64*,int *,int,
						void *,void *);
	int			(*thinned_avg)(struct matrix_data_type *,
						struct matrix *,
						INTEGER64*,int,
						void *,void *);
	int			(*v_add)(struct matrix_data_type *,
						struct matrix *,
						INTEGER64*,int,void *,
						void *,void *,void *);
	int			(*v_sub)(struct matrix_data_type *,
						struct matrix *,
						INTEGER64*,int,void *,
						void *,void *,void *);

	void			(*endian_to_net)(void *);
	void			(*endian_to_host)(void *);
	void			(*convert_to_net)(struct matrix_data_type *,
						RECORD_LIST64 * rlp,void *);
	void *			(*convert_to_host)(struct matrix_data_type *,void *,int,void *);

	void * 			(*add_vv)(struct matrix_data_type *,
					void *,void *,
					struct mx_cache *);
	void * 			(*sub_vv)(struct matrix_data_type *,
					void *,void *,
					struct mx_cache *);
	void * 			(*mul_mm)(struct matrix_data_type *,
					void *,void *,
					struct mx_cache *);
	void * 			(*mul_sv)(struct matrix_data_type *,
					void *,void *,
					struct mx_cache *);
	void * 			(*trans_m)(struct matrix_data_type *,
					void *,
					struct mx_cache *);
	void 			(*get_zero)(struct matrix_data_type *,
					void *);
	void 			(*get_el)(struct matrix_data_type *,
					void *);

	void			(*print_data)(
					struct matrix_data_type*,
					MATRIX_STRING_BUFFER * msb,
					void *,char*fmt);
} MATRIX_DATA_TYPE;


typedef struct mblk {
	struct mblk *		next;
	unsigned short		size;
	unsigned short		cnt;
	char *			alloc_file;
	int			alloc_line;
	char *			free_file;
	int			free_line;
} MBLK;

#define MBLK_ALLOC		0xffff

#define MBLK_LOGSIZE		9
#define MBLK_HASHSIZE		16

typedef struct mx_cache {
	MATRIX * 		m;
	MATRIX_NODE *		n;
	MATRIX_DH_SET *		ds;
	int *			access_ch;
	int			ds_len;
	int			dirty;

	MBLK **			mblk_hash;

	int			mblk_hashsize;
	int			mblk_logsize;
	int			gn_tree_node;
	int			gn_create;
	int			gn_wait;
} MX_CACHE;

typedef struct mx_cache_param_ix {
	unsigned short		p;
	unsigned short		x;
} MX_CACHE_PARAM_IX;

typedef struct mx_cache_param {
	INTEGER64 *		dc;
	int *			ofs;
#define MXC_PTR_LEN	4
#define MXC_INVALID	0xffff
	void *			data_ptrs[MXC_PTR_LEN];
	MX_CACHE_PARAM_IX *	data_ix;
	MX_CACHE *		c;

	/* data access param */

	void *			ret_buf;
	void *			inp_buf;
	int			inp_level;
	int			status;
#define MXCS_OK			0
#define MXCS_OUTOFMATRIX	1

	/* newton option */

	double			tolerance;
	int			try_max;
	double			result_tolerance;
	void *			avg_mtx;
} MX_CACHE_PARAM;

typedef struct mx_dim_code_list {
	struct mx_dim_code_list * 	next;
	INTEGER64 *			dc;
} MX_DIM_CODE_LIST;

#define ME_ERROR		(-100)
#define ME_NO_NODE		(-101)
#define ME_ERR_NODE		(-102)
#define ME_PROC_NODE		(-103)
#define ME_INDEX_OVER		(-104)
#define ME_DIM			(-105)
#define ME_DIM_DIVIDE		(-106)
#define ME_CHANNEL_INFO		(-107)
#define ME_CHANNEL_NOS		(-108)
#define ME_BLOCK_SIZE		(-109)
#define ME_TOTAL_LEVELS		(-110)
#define ME_PRI_AREA		(-111)
#define ME_OPEN_METHOD		(-112)
#define ME_FETCH_METHOD		(-113)
#define ME_FLAGS		(-114)
#define ME_NEW_TOKEN		(-115)
#define ME_FREE_TOKEN		(-116)
#define ME_TRIGGER		(-117)
#define ME_MODIFY_TIME		(-118)

#define ME_INVALID_INST		(-119)
#define ME_CAL_ERROR		(-120)

#define ME_MATRIX_ERR		(-121)
#define ME_DATA_ACCESS		(-122)

#define ME_CANNOT_OPEN_FILE	(-122)
#define ME_DESTROY_FILE		(-123)

/* xlerror application code */

#define XL_AC_FILE		1
#define XL_AC_NODE		2
#define XL_AC_NETWORK		3


/*

DIM-CODE:
(dim-code me)
(dim-code [level] [code-1] [code-2] ....)
MATRIX


*/

/* matrix_error application code */

#define AME_TRAP	1
#define AME_INTERRUPT	2

/* get_matrix_node(tree) access patteren */

#define GN_READ_ONLY	(-1)
#define GN_NODE_CREATE	0
#define GN_LIST_CREATE	1
#define GN_ERROR_NORETRY 2

#define GN_TREE		1
#define GN_NODE		0

/* matrix_node_channel_unlock flags */

#define NF_DIRTY		0x00000001

/* pt_dc fmt */
#define PTDC_NODE_ID	1
#define PTDC_PIXEL_1	2

void init_matrix();
MATRIX_NODE * get_matrix_node(int * errp,MATRIX * m,
			INTEGER64 * dim_code,int access,MATRIX_TOKEN*);
INTEGER64 * get_dim_code_from_sexp(XL_SEXP * );
XL_SEXP * get_channel_data(MATRIX_NODE * n,int ch,XL_SEXP * s);
XL_SEXP * matrix_error(char*,XL_SEXP *,int code,XL_SEXP *);
INTEGER64 * copy_dim_code(MATRIX * m,INTEGER64 * dim_code);
XL_SEXP * get_sexp_from_dim_code(MATRIX * m,INTEGER64*);
int * get_dim_code_from_sexp_int(XL_SEXP * s);

MATRIX * open_matrix(L_CHAR * neturl,L_CHAR * filename,L_CHAR * key,
			void (*open_method)(MATRIX_TOKEN*),void * );
void close_matrix(MATRIX * m);
MATRIX * search_matrix(int *,L_CHAR * neturl,L_CHAR * filename,L_CHAR * key,MATRIX_TOKEN * t);
int set_channel_sexp(MATRIX_NODE*,int,XL_SEXP*);
void matrix_node_channel_unlock(MATRIX_NODE * n,int flags);
void matrix_node_channel_lock(MATRIX_NODE * n);
void set_matrix_mode(MATRIX * m,int mode);
void matrix_trigger_access(MATRIX_NODE * n,int access,int clear_err);

void init_mxCH(XLISP_ENV * env);
void init_mxSet(XLISP_ENV * env);
void init_mxTrigger(XLISP_ENV * env);
void init_mxAdd(XLISP_ENV * env);
void init_mxDiff(XLISP_ENV * env);
void init_mxThinnedOut(XLISP_ENV * env);
void init_mxCompressJPEG(XLISP_ENV * env);
void init_mxUncompressJPEG(XLISP_ENV * env);
void init_mxLoad(XLISP_ENV * env);
void init_mxSave(XLISP_ENV * env);
void init_mxFinish(XLISP_ENV * env);
void init_mxUncompressOldFormat(XLISP_ENV * env);
void init_mxCompressZ(XLISP_ENV * env);
void init_mxUncomressZ(XLISP_ENV * env);
void init_mxCompound(XLISP_ENV * env);
void init_mxSeparate(XLISP_ENV * env);
void init_mxSquash(XLISP_ENV * env);
void init_mxStuffing(XLISP_ENV * env);



int set_matrix_channel_info(MATRIX * m,int ch,MATRIX_CHANNEL_INFO * inf);
int set_matrix_param(MATRIX * m,MATRIX_PARAM * p);
int set_matrix_dim_divide(MATRIX * m,int dim,int dim_divide);
int set_matrix_block_size(MATRIX * m,int dim,int block_size);
int set_matrix_pixel_size(MATRIX * m,int dim,INTEGER64 pixel_size);
int set_matrix_cal(MATRIX * m,int id,XL_SEXP * cal);
int set_matrix_cal_equ(MATRIX * m,int id,int id2);


void *mxt_alloc_copy(MATRIX_DATA_TYPE * tp,void * d,int,void*);
void * xx_mxt_alloc_data(MATRIX_DATA_TYPE * tp,int,void * d,void *w,
		char*,int);
#define mxt_alloc_data(tp,atype,d,w)	\
	xx_mxt_alloc_data(tp,atype,d,w,__FILE__,__LINE__)
void mxt_free_data(struct matrix_data_type*,void *);
void * xx_atype_alloc(int,int,void *,char*,int);
#define atype_alloc(sz,atype,w)	\
	xx_atype_alloc(sz,atype,w,__FILE__,__LINE__)

extern MATRIX_DATA_TYPE mx_type_bit;
extern MATRIX_DATA_TYPE mx_type_bit_v;
extern MATRIX_DATA_TYPE mx_type_int8;
extern MATRIX_DATA_TYPE mx_type_int8_v;
extern MATRIX_DATA_TYPE mx_type_uint8;
extern MATRIX_DATA_TYPE mx_type_uint8_v;
extern MATRIX_DATA_TYPE mx_type_int16;
extern MATRIX_DATA_TYPE mx_type_int16_v;
extern MATRIX_DATA_TYPE mx_type_uint16;
extern MATRIX_DATA_TYPE mx_type_uint16_v;
extern MATRIX_DATA_TYPE mx_type_int32;
extern MATRIX_DATA_TYPE mx_type_int32_v;
extern MATRIX_DATA_TYPE mx_type_uint32;
extern MATRIX_DATA_TYPE mx_type_uint32_v;
extern MATRIX_DATA_TYPE mx_type_int64;
extern MATRIX_DATA_TYPE mx_type_int64_v;
extern MATRIX_DATA_TYPE mx_type_uint64;
extern MATRIX_DATA_TYPE mx_type_uint64_v;
extern MATRIX_DATA_TYPE mx_type_float;
extern MATRIX_DATA_TYPE mx_type_float_v;
extern MATRIX_DATA_TYPE mx_type_double;
extern MATRIX_DATA_TYPE mx_type_double_v;
extern MATRIX_DATA_TYPE mx_type_block;
extern MATRIX_DATA_TYPE mx_type_string;
extern MATRIX_DATA_TYPE mx_type_string_v;
extern MATRIX_DATA_TYPE mx_type_sexp;
extern MATRIX_DATA_TYPE mx_type_RGB;
extern MATRIX_DATA_TYPE mx_type_RGB_v;

void *  mxt_vector_sexp2md(int * cpy,struct matrix_data_type* tp,XL_SEXP * s);
XL_SEXP * mxt_vector_md2sexp(struct matrix_data_type*,void * d);
void  mxt_vector_copy(struct matrix_data_type* tp,void* d1,void* d2,int,void*);
int mxt_vector_get_size(MATRIX_DATA_TYPE * tp,void * d);
void * xx_mxt_alloc_vector(MATRIX_DATA_TYPE * tp,
		int atype,void * d,void *w,char* ,int);
#define mxt_alloc_vector(tp,atype,d,w) \
	xx_mxt_alloc_vector(tp,atype,d,w,__FILE__,__LINE__)

void lock_save(MATRIX_NODE *);
void unlock_save(MATRIX_NODE*);
void get_matrix_dh_set(MATRIX_DH_SET * dh,void * d);
int cmp_dh_set(MATRIX_DH_SET*,MATRIX_DH_SET*);
void unlock_node(MATRIX_NODE * n,MATRIX_TOKEN * t);
int
cmp_dim_code(MATRIX * m,INTEGER64 * dc1,INTEGER64 * dc2);


void _xx_insert_matrix_sexp(MATRIX_SEXP * d,char * ,int);
#define _insert_matrix_sexp(x)	_xx_insert_matrix_sexp(x,__FILE__,__LINE__)
void get_ix_from_seq(int * target,int * ix_size,int ix,int dim);
int get_seq_from_ix(int * ix,int * ix_size,int dim);
int inc_ix(int * ix,int * st,int * inc,int * ix_size,int dim);
void round_int(char type,void * dest,INTEGER64 src,int );
void
insert_dim_code_index(MATRIX_NODE * n,INTEGER64 * dim_code,int dirty);

unsigned char __short2uchar(short in);
short __uchar2short(unsigned char in);
void insert_matrix_type_table(MATRIX_DATA_TYPE *);
MATRIX_DATA_TYPE * get_matrix_data_type(int type);
void *get_vdata_from_sexp(XL_SEXP * s);
void *
mxt_alloc_vector_by_dim_code(MATRIX * m,MATRIX_DATA_TYPE * tp,int atype,INTEGER64 * dim_code,void * def);

void gc_matrix_lock();
void gc_matrix_unlock();
void gc_matrix();

void *
get_matrix_node_channel(int * errp,MATRIX_NODE ** np,
		MATRIX * m,INTEGER64 * dim_code,
		int ch,int type,int access,
		MATRIX_ALLOC_VECTOR_PARAM*);
void
matrix_peano_trigger(
	MATRIX * m,
	INTEGER64 * dc_start,
	INTEGER64 * dc_end,
	int _access);

unsigned char *
get_compressed_code64(unsigned char * ptr,INTEGER64 in);
unsigned char *
get_uncompressed_code64(INTEGER64 * retp,unsigned char * ptr);
unsigned char*
get_compressed_dim_code(unsigned char * ptr,INTEGER64 * dim_code,int dim);
unsigned char*
get_uncompressed_dim_code(
	INTEGER64 * dim_code,unsigned char * ptr);
int get_dim_code_dimension(unsigned char * ptr);
int save_matrix_header(MATRIX * m);
int load_matrix_header(MATRIX * m,int oflags,int mode);
void *
load_matrix_data(
	INTEGER64 * next_fofs,
	int *	id,
	MATRIX * m,
	INTEGER64 fofs,
	MATRIX_DATA_TYPE * tp);
INTEGER64
save_matrix_data_1(
	MATRIX * m,
	INTEGER64 fofs,
	void * target,
	MATRIX_DATA_TYPE * tp);
INTEGER64
save_matrix_data_2(
	MATRIX * m,
	INTEGER64 fofs,
	void * target,
	INTEGER64 next_fofs,
	int id,
	MATRIX_DATA_TYPE * tp);
int
load_matrix_dim_addr(MATRIX_NODE * n,INTEGER64 addr_fofs);
int save_matrix_node(MATRIX_NODE * n);
int load_matrix_node(MATRIX_NODE * n);
void close_matrix_file(MATRIX * m);
int matrix_standard_write_file(MATRIX_TOKEN * t);
int matrix_standard_read_file(MATRIX_TOKEN * t);
void
set_access_jump(MATRIX_TOKEN * t,
	int err_jump,int normal_jump,int err_jump_status,int normal_jump_status);
int
load_mode_cal(XL_SEXP ** cals,int * pri,MATRIX * m,int mode);
int
save_mode_cal(MATRIX * m,int mode,char *** cals,int * pri);



extern SEM matrix_lock;

void mxt_endian_nothing(void *);
void mxt_endian_vector_to_host(void *);
void mxt_endian_vector_to_net(void *);
void
mxt_convert_basic_to_net(MATRIX_DATA_TYPE * tp,RECORD_LIST64 * rlp,void * d);
void *
mxt_convert_basic_to_host(MATRIX_DATA_TYPE * tp,void * d,int atype,void * at_work);
void
xx_insert_matrix_access(MATRIX_TOKEN * t,void (*func)(),char*,int);
#define insert_matrix_access(t,f)	xx_insert_matrix_access(t,f,__FILE__,__LINE__)
void matrix_token_error(MATRIX_TOKEN * t);
void init_mx_file();
void matrix_exec_cal(MATRIX_TOKEN * t);
void close_all_matrix();
void token_check(MATRIX_TOKEN * t);
void allset_dim_code_index(MATRIX_NODE * n,int dirty);
MATRIX_NODE *
get_matrix_node_wait(int * errp,MATRIX * m,INTEGER64 * dim_code,
			int access);

void xx_check_point(MATRIX_TOKEN * ,char *,int);
#define check_point(t)	xx_check_point(t,__FILE__,__LINE__)

void flush_mx_cache(MX_CACHE * c,int);
int get_mx_cache(MX_CACHE * c,INTEGER64 * src);
int write_mx_cache(MX_CACHE_PARAM * p);
int read_mx_cache(MX_CACHE_PARAM * p);

MX_DIM_CODE_LIST *
mx_search_level_node(MATRIX * m,INTEGER64 * last_dc,int limit);

void * mxt_mul_mm(void *,void *,MX_CACHE *);
void * mxt_mul_sv(void *,void *,MX_CACHE *);
void * mxt_add_vv(void *,void *,MX_CACHE *);
void * mxt_sub_vv(void *,void *,MX_CACHE *);
void * mxt_trans_m(void *,MX_CACHE *);
void * mxt_compound_vv(void * d1,void * d2,int ix,MX_CACHE *);
void * mxt_e_m(MATRIX_DATA_TYPE * tp,int,MX_CACHE *);

int inc_dim_code_ix(INTEGER64 * target,INTEGER64 * dc,INTEGER64 * inc,INTEGER64 * end_pos,int dim);
int read_mx_ip_double(MX_CACHE_PARAM * p);
int read_mx_ip_float(MX_CACHE_PARAM * p);
void * read_mx_ipdiff_double(MX_CACHE_PARAM * p);
void * read_mx_ipdiff_float(MX_CACHE_PARAM * m);
MX_DIM_CODE_LIST * 
get_children_list(int * errp,MATRIX * m,INTEGER64 * dc,
	int access,int wait_flag,MATRIX_TOKEN*);
INTEGER64 * get_dim_code_from_index(MATRIX * m,INTEGER64 * dc,int ix);
void * mxt_get_matrix_from_ary(MATRIX_DATA_TYPE *,void * ary,int,int,
			MX_CACHE *);
char * mxt_print(MATRIX_DATA_TYPE* tp,void * d,char*fmt);
void
mxt_print_vector(
	MATRIX_DATA_TYPE * tp,
	MATRIX_STRING_BUFFER * b,
	void * d,char*fmt);
int matrix_newton_double(MX_CACHE_PARAM *);
int matrix_newton_float(MX_CACHE_PARAM *);
void * resolve_equation_double(void *,void *,MX_CACHE*);
void xx_mxc_free(MX_CACHE * c,void * ptr,char*,int);
#define mxc_free(c,ptr)	xx_mxc_free(c,ptr,__FILE__,__LINE__)
void * xx_mxc_alloc(MX_CACHE * c,int size,char * f,int l);
#define mxc_alloc(c,size)	xx_mxc_alloc(c,size,__FILE__,__LINE__)
void mxc_setup(MX_CACHE *);
void wait_matrix_mode(MATRIX * m);
void flush_all_dirty_file(MATRIX * m);
void sync_matrix(MATRIX * m);
void free_mx_dim_code_list(MX_DIM_CODE_LIST * lst);
char * pt_dc(MATRIX * m,INTEGER64 * dc,int fmt);
void set_matrix_env(MATRIX * m,char * name,char * data);
void load_indicate(int start);
void minimum_matrix_init(int,char**);
void out_matrix_string_buffer(MATRIX_STRING_BUFFER * b,char * str);
char * get_matrix_string_buffer(MATRIX_STRING_BUFFER*);
void free_matrix_string_buffer(MATRIX_STRING_BUFFER*b);

#endif

