00001 /* 00002 The Malete project - the Z39.2/Z39.50 database framework of OpenIsis. 00003 Version 0.9.x (patchlevel see file Version) 00004 Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Lesser General Public 00008 License as published by the Free Software Foundation; either 00009 version 2.1 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00014 See the GNU Lesser General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public 00017 License along with this library; if not, write to the Free Software 00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 00020 see README for more information 00021 EOH */ 00022 #ifndef PW_H 00023 00024 /* 00025 $Id: pw.h,v 1.2 2005/02/23 17:09:52 kripke Exp $ 00026 interface of the Malete patchwork 00027 */ 00028 00029 #define PW_VERSION "1.0" 00030 00031 00032 #include "core.h" 00033 00034 00035 typedef struct Obj Obj; 00036 00037 00038 /* ****************************************************************** */ 00039 /* */ 00040 /* HASH TABLE */ 00041 /* */ 00042 /* ****************************************************************** */ 00043 00044 #define HEDEFKEYLEN 1 00045 00046 typedef struct HEntry HEntry; 00047 /* hmmm ... maybe this should become part of Obj */ 00048 struct HEntry { 00049 HEntry *nxt; 00050 Obj *obj; 00051 int hv; /* hash value of this entry */ 00052 #ifndef NDEBUG 00053 int dpt; 00054 #endif 00055 int len; 00056 char key[HEDEFKEYLEN]; /* not 0 terminated */ 00057 }; 00058 00059 /* hmmm ... maybe this should become part of Struct */ 00060 typedef struct HTable { 00061 List *list; 00062 int mask; 00063 int nume; /* # of entries */ 00064 int dsize; /* # bytes of unlinked entries */ 00065 #ifndef NDEBUG 00066 int coll; /* # of collisions */ 00067 #endif 00068 } HTable; 00069 00070 #define HSIZ(t) (-((t)->list->fld->tag)-1) /* number of buckets */ 00071 #define HSHIFT 1 /* rebuild factor: HSIZ(t) << HSHIFT */ 00072 #define HESIZ(he) (sizeof(HEntry)+(he)->len-HEDEFKEYLEN) /* entry size */ 00073 #define HINITIAL 32 /* initial # of buckets */ 00074 #define HMAXLOAD 75 /* max load factor */ 00075 #define HCURLOAD(t) ( (100*(t)->nume) / HSIZ(t) ) /* current load */ 00076 #define HSHRINKLOAD 25 /* shrink, if HCURLOAD(t) < HSHRINKLOAD */ 00077 #define HMAXFRAG 50 /* max fragmentation factor */ 00078 #define HCURFRAG(t) ( (100*((t)->dsize)) / LSIZ((t)->list) ) /* current frag */ 00079 00080 00081 extern HEntry* OPT_STDCALL hGet ( HTable *table, const char *key, int len ); 00082 extern HEntry* OPT_STDCALL hAdd ( HTable *table, const char *key, int len ); 00083 extern HEntry* OPT_STDCALL hSet ( HTable *t, const char *key, int len, Obj *o ); 00084 extern int OPT_STDCALL hDel ( HTable *table, const char *key, int len ); 00085 extern HTable* OPT_STDCALL hInit ( HTable *table, const char* header ); 00086 extern void OPT_STDCALL hFini ( HTable *table ); 00087 00088 /* free al resources held by table */ 00089 #define HFREE( table ) do { \ 00090 hFini( (table) ); \ 00091 mFree( table ); \ 00092 } while (0) 00093 00094 #ifndef NDEBUG 00095 /* debug statistics */ 00096 extern void OPT_STDCALL hstat ( HTable *table ); 00097 # define HSTAT(t) hstat(t); 00098 #else 00099 # define HSTAT(t) 00100 #endif 00101 00102 00103 00104 /* ****************************************************************** */ 00105 /* */ 00106 /* OBJECTS AND MESSAGES */ 00107 /* */ 00108 /* ****************************************************************** */ 00109 00110 typedef Fld * Msg; 00111 typedef struct Qry Qry; /* query implemented by dbo */ 00112 00113 00114 /* 00115 dispatch message "msg", starting at object obj. 00116 00117 ----------------------------------- 00118 Syntax and semantics of messages 00119 00120 A message is basically an array of fields - usually of length 1. The leader 00121 of this array containes the messagename, denoting a method, and possibly 00122 options. The mesagename has to be given in the leader's primary value, the 00123 options in following subfields. Data to be processed is contained in the 00124 following fields - if any. The messagename may contain subobject specifiers, 00125 which have to be separated by a '.'. Besides this the evaluation of the 00126 given leader is solely in the responsibility of the method invoked. The 00127 message evaluation may change the given message. The significant length of a 00128 messagename may be limited to four bytes. A leader should not be longer 00129 than DEFBLKLEN bytes, though some messages may allow longer sizes. Some 00130 messagenames may use special characters denoting a special treatment of the 00131 given leader - thus such characters should not be used for ordinary 00132 messagenames. The result of the evaluation, if any, is always written to 00133 env.out. 00134 */ 00135 typedef int OPT_STDCALL disp ( Obj *self, Msg msg ); 00136 00137 /* 00138 the general form of an object 00139 send it a message using that->snd(msg) 00140 In general, snd must return <0 on error, >=0 else 00141 */ 00142 struct Obj { 00143 disp *snd; /* method implementation */ 00144 }; 00148 extern int OPT_STDCALL oObj ( Obj *self, Msg msg ); 00149 00150 00151 typedef struct Struct Struct; 00152 00153 typedef Obj* OPT_STDCALL factory ( Struct *self, const char *key, int len ); 00154 /* 00155 an object with variable number of childs 00156 */ 00157 struct Struct { 00158 disp *snd; /* method implementation */ 00159 HTable *reg; /* child registry */ 00160 factory *fac; /* child factory */ 00161 }; 00165 extern int OPT_STDCALL oStruct ( Struct *self, Msg msg ); 00166 00167 00171 typedef struct Ses { 00172 disp *snd; 00173 HTable *reg; /* main registry */ 00174 factory *fac; /* main factory */ 00175 Sink *out; /* main env.out for this session */ 00176 Sink *err; /* env.err for this session */ 00177 unsigned rid; /* last rid written */ 00178 Qry *qry; /* array of q queries */ 00179 lolo req; /* request counter */ 00180 /* options */ 00181 char *at; /* default target */ 00182 unsigned r; /* max # of records per read, 0 = unlimited */ 00183 unsigned q; /* max # of open query cursors != 0 */ 00184 unsigned s; /* max # of results in search set, 0 = unlimited */ 00185 } Ses; 00186 extern int OPT_STDCALL oSes ( Ses *self, Msg msg ); 00187 00188 /* 00189 default main factory (i.e. for the session). 00190 scans the environment options for defined objects 00191 */ 00192 extern Obj* OPT_STDCALL facMain ( Ses *self, const char *key, int len ); 00193 00194 /* init session */ 00195 extern void sInit (Ses *s); 00196 00197 00198 extern Ses *ses; /* current session */ 00199 00200 /* 00201 main dispatcher 00202 */ 00203 #define dispatch( msg ) ses->snd((Obj*)ses, msg) 00204 00205 00206 /* 00207 object linked to a session on some remote server 00208 */ 00209 typedef struct Srv { 00210 disp *snd; /* method implementation */ 00211 file *con; /* connection */ 00212 } Srv; 00216 extern int OPT_STDCALL oSrv ( Srv *self, Msg msg ); 00217 00218 00219 /* 00220 database object 00221 NOTE that these are childs of session, so all status is per session. 00222 */ 00223 typedef struct Dbo { 00224 disp *snd; 00225 HTable *reg; /* views etc */ 00226 factory *fac; /* child factory */ 00227 Db *db; /* shared by the Dbos */ 00228 Qry *qry; /* chain of queries */ 00229 unsigned qid; /* number of last query, 0 = none */ 00230 unsigned rid; /* number of last written rec, 0 = none */ 00231 /* options */ 00232 unsigned p; /* position limit for snapshot read, 0 = none */ 00233 } Dbo; 00237 extern int OPT_STDCALL oDbo ( Dbo *self, Msg msg ); 00238 00239 extern Dbo *newDbo ( char *name ); /* constructor */ 00240 extern void delDbo ( Dbo *self ); /* destructor */ 00241 00242 00243 /* ****************************************************************** */ 00244 /* */ 00245 /* HANDLERS FOR VARIOUS STANDARD MESSAGES */ 00246 /* */ 00247 /* ****************************************************************** */ 00248 00249 00250 /* 00251 Process a pipe message '|'. 00252 The leader is parsed for the subfields '|'. Each of which should contain a 00253 valid messagename, options may be given in following subfields terminated by 00254 the next '|' subfield or the end of the leader. The output of the first 00255 method is used as data input for the next and so on. The first submessage 00256 may start directly after the primary field w/o the '|' identifier. 00257 */ 00258 extern int OPT_STDCALL mPipe ( Obj *self, Msg msg ); 00259 00260 /* 00261 Process a compound message ';'. 00262 The leader is parsed for the subfields ';'. Each of which should contain a 00263 valid messagename, options may be given in following subfields terminated by 00264 the next ';' subfield or the end of the leader. Each message is processed 00265 separately, given data is used for all messages. The first submessage may 00266 start directly after the primary field w/o the ';' identifier. 00267 */ 00268 extern int OPT_STDCALL mComp ( Obj *self, Msg msg ); 00269 00270 /* 00271 Process a comment message '#'. 00272 */ 00273 extern int OPT_STDCALL mComm ( Obj *self, Msg msg ); 00274 00275 00276 #define PW_H 00277 #endif /* PW_H */