
#ifndef TRUE
#define FALSE 0
#define TRUE (!FALSE)
#endif
#ifndef BFSZ
#define BFSZ 600
#endif
#define HASH_WORDS 20000
#define NPOINT 4

/*



10 bytes, 2 byte free blocks, 4 bytes, 4
word 10, freeblocks 2, curlist 4 
60 * 6000000 
*/
/* 32 *200000 = 6,400,000 , 1000000 = 32MB */

#define MAX_WORD_LEN 12
typedef struct MWord {
	int wstart; 	/* Position in word file			*/
	int start; 	/* First reference in pointer file 		*/
	int upto;  	/* Next place to write a pointer, -1 if none 	*/ 
	short nfree;  	/* How many free bits 				*/
	short nused; 	/* How many total bits, maybe not necessary  	*/ 
	char word[MAX_WORD_LEN]; 
	struct MWord *next;  
} MWORD;

typedef struct WWord {
	int start; 	/* First reference in pointer file 		*/
	int upto;  	/* Next place to write a pointer, -1 if none 	*/ 
	short nfree;  	/* How many free bits 				*/
	short nused; 	/* How many total bits, maybe not necessary  	*/ 
	char word[MAX_WORD_LEN]; 
} WWORD;

 
/* typedef struct Glist {char *word; int idx; struct Glist *next;} GLIST;*/

typedef struct Vlist {int gid; int num; int score; int xtime; struct Vlist *next;} VLIST;
typedef struct Dlist {int gid; int num; int used; struct Dlist *next;} DLIST;
typedef struct Wcache {MWORD *dict; VLIST *list; struct Wcache *next;} WCACHE; 
/*typedef struct Pointx {short group; int item; char score; unsigned short xtime;} DPOINT;*/
typedef struct Glist {char *word; int idx; struct Glist *next;} GLIST;

#define PSIZE 7
#define PSIZEX 9
/* Base the item from the group with 32K signed offset either way.  */
/* 5 bytes */


enum {I_HEADERS, I_ITEM_WORDS, I_WORD_MAX, I_WORD_TOTAL, I_INDEX_TIME, I_MAX_GROUPS, I_INDEX_NUMBERS
,I_INDEX_ASIAN, I_INDEX_ALL
};
#ifdef FTSMAIN
char *fini_names[]={"headers","item_words","word_max","word_total", "index_time", "max_groups", "index_numbers"
, "index_asian", "index_all"
, NULL };
#endif

int fts_group_base(int i, int num);
int fts_write_group(void);



typedef struct Wlist {MWORD *dict; int score; struct Wlist *next;} WLIST;
#define U_HASH 1000
#define HASH_CACHE 5000

/*---------------------------------------------------------*/
int fts_mem(void);
void fts_init(char *rt, int isread);
void fts_close(void);
void fts_index_write(void);
MWORD *fts_index_find(char *s);


MWORD *fts_word_add(char *word);
MWORD *fts_word_add_hash(MWORD *w);
int fts_point_seek(FILE *fp, int go);

MWORD *fts_word_find(char *word);
MWORD *fts_word_find_add(char *word);
int fts_word_update(MWORD *w);
VLIST *fts_read(MWORD *w);
int fts_group_add(char *word, int idx, int num);
void fts_stats(int *nwords, int *nuni);
void fts_test_word(char *wordlist);

int fts_read_words(void);
int fts_word_append(FILE *fw, MWORD *word);
int fts_open_new(void);
int fts_point_write(FILE *fp, int gid, int num, int score, int xtime);
					
void fts_read_groups(void);
int fts_group_find(char *word);
void fts_append_group(char *group, int idx, int num);
void fts_uni_add(char *word);
int fts_add(char *group, int num, char *article);
int fts_fix_word( char *s);
void fts_uni_cache(char *group, int num, int xtime);
void fts_cache_add(MWORD *dict, int score, int gid, int num, int xtime);
void fts_cache_addv(WCACHE *list,MWORD *dict, int score, int gid, int num, int xtime);
void fts_cache_write(void);
void fts_cache_write_one(FILE *fp, FILE *fw, MWORD *dict, VLIST *list);
int fts_open(void);
void fts_word_open(void);
int fts_append(FILE *fp,int gid, int num, int score);
int fts_search(char *terms[], int nterms, int isand, char *gwild, int xsince, int xbefore, int stype	       , int r_terms[], int from, int to, char * r_name[] 	       , int r_num[], int r_score[], int r_xtime[]);
void fts_trigger(void);

void fts_expire(void);
int fts_hash(char *s, int max);
char *fts_dir(char *s);
void fts_searchtest(char *wordlist);
int fts_write_words(void);
void fts_mark_del(int g, int num);
int fts_is_del(int gid, int num);
void fts_free_del(void);

int fts_ini_find(char *s);
char *fts_ini(int x);
int fts_true(int x);
int fts_read_ini(void);
int fts_add_line(char *s);





