⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mal_module.mx

📁 一个内存数据库的源代码这是服务器端还有客户端
💻 MX
📖 第 1 页 / 共 2 页
字号:
@' The contents of this file are subject to the MonetDB Public License@' Version 1.1 (the "License"); you may not use this file except in@' compliance with the License. You may obtain a copy of the License at@' http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html@'@' Software distributed under the License is distributed on an "AS IS"@' basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the@' License for the specific language governing rights and limitations@' under the License.@'@' The Original Code is the MonetDB Database System.@'@' The Initial Developer of the Original Code is CWI.@' Portions created by CWI are Copyright (C) 1997-2007 CWI.@' All Rights Reserved.@a M. L. Kersten@+ Module ManagementThe operations are organized in separate MAL modules.Each module contains a local symbol table of all function namesknown to it so far. These names are stored in the global namespacepool and never removed to guarantee stability of remote references.All dynamically loaded functions remain in existingfor the duration of the server session. Only the administrator canload functions (upon system restart). Therefore, we do not haveto lock the dictionary table while traversing it for information.Global (private) variables can be realized keeping the symbol tableand runtime stack around between requests.@{The symbol descriptors within a scope are organized in a list of subscopes indexed by the first character of the function name.The modules are still collected in a linked list to ease accessand debug its content. It should be used with care for resolving unknown modules.The function symbols are collected in a global name space table,indexed by a small hash table. Once added, the name may not be removed anymore.Care should be taken not to generate many unique function names.@h#ifndef _MAL_SCOPE_H_#define _MAL_SCOPE_H_#include "mal_box.h"#include "mal_xml.h"/* #define MAL_SCOPE_DEBUG  */#define MAXSCOPE 256typedef struct SCOPEDEF {	struct SCOPEDEF   *outer; /* outer level in the scope tree */	struct SCOPEDEF   *sibling; /* module with same start */	str	    name;			/* index in namespace */	int		inheritance; 	/* set when it plays a role in inheritance */	Symbol *subscope; 		/* type dispatcher table */	Box box;    			/* module related objects */	int isAtomModule; 		/* atom module definition ? */	void *dll;				/* dlopen handle */	str help;   			/* short description of module functionality*/} *Module, ModuleRecord;mal_export Module    mal_scope;  /* the start of the module list */mal_export void     setModuleJump(str nme, Module cur);mal_export Module   newModule(Module scope, str nme);mal_export Module   fixModule(Module scope, str nme);mal_export void     freeModule(Module cur);mal_export void     freeModuleList(Module cur);mal_export void     insertSymbol(Module scope, Symbol prg);mal_export void     deleteSymbol(Module scope, Symbol prg);mal_export void		setInheritanceMode(Module head,int flag);mal_export Module	setInheritance(Module head,Module first, Module second);mal_export Module   findModule(Module scope, str name);mal_export Symbol   findSymbolInModule(Module v, str fcn);mal_export Symbol   findMALSymbol(str mod, str fcn);mal_export int      displayModule(stream *f, Module v, str fcn,int listing);mal_export void     showModules(stream *f, Module v);mal_export void     debugModule(stream *f, Module v, str nme);mal_export void     dumpManual(stream *f, Module v, int recursive);mal_export void     dumpManualSection(stream *f, Module v);mal_export void 	dumpManualHelp(stream *f, Module s, int recursive);mal_export void 	dumpHelpTable(stream *f, Module s, str text, int flag);mal_export void 	dumpSearchTable(stream *f, str text);mal_export void     dumpManualOverview(stream *f, Module v, int recursive);mal_export void     dumpManualHeader(stream *f);mal_export void     dumpManualFooter(stream *f);mal_export void     showModuleStatistics(stream *f,Module s); /* used in src/mal/mal_debugger.c */mal_export char **getHelp(Module m, str pat, int flag);mal_export char **getHelpMatch(char *pat);mal_export void showHelp(Module m, str txt,stream *fs);#define getSubScope(N)  (*(N))#endif /* _MAL_SCOPE_H_ */@+ Module scope managementUpon system restart, the global scope is created. It is called "root" anddoes not contain any symbol definitions. It merely functions as an anchorpoint for the modules to be added later.@= newscope	if( nme == NULL){		GDKfatal("@1:unexpected name (=null)\n");	}	cur = (Module) GDKzalloc(sizeof(ModuleRecord));	if( cur == NULL){		GDKfatal("@1: cannot initialize scope\n");	}	cur->name = nme;	cur->outer = NULL;	cur->sibling = NULL;	cur->inheritance = TRUE;	cur->subscope = NULL; 	cur->isAtomModule = FALSE;@c#include "mal_config.h"#include "mal_module.h"#include "mal_function.h"   /* for printFunction() */#include "mal_namespace.h"#include "mal_client.h"#include "mal_interpreter.h"Module mal_scope;    /* the root of the tree */Module scopeJump[256][256];  /* to speedup access to correct scope */void newSubScope(Module scope){	int len = (MAXSCOPE)*sizeof(Module);	scope->subscope = (Symbol *) GDKzalloc(len);}@-Definition of a new module scope may interfere with concurrentactions of multiple threads. This calls for a secure update of the scope tree structure. A jump table is mainted to provide a quick start in the moduletable to find the correct one. This simple scheme safes about100ms/100K calls@cvoid clrModuleJump(str nme, Module cur){		if( scopeJump[(int)(*nme)][(int)(*(nme+1))]== cur)			scopeJump[(int)(*nme)][(int)(*(nme+1))]= cur->sibling;}void setModuleJump(str nme, Module cur){		cur->sibling= scopeJump[(int)(*nme)][(int)(*(nme+1))];		scopeJump[(int)(*nme)][(int)(*(nme+1))]= cur;}Module newModule(Module scope, str nme){	Module cur;	nme= getName(nme,strlen(nme));	@:newscope(newModule)@	newSubScope(cur);	if( scope != NULL){		cur->outer = scope->outer;		scope->outer= cur;		setModuleJump(nme,cur);	} 	return cur;}Module cpyModule(Module scope){	Module nxt= NULL;	Module cur;	str nme;	if( scope->outer) nxt= cpyModule(scope->outer);	nme= GDKstrdup(scope->name);	@:newscope(newModule)@	newSubScope(cur);	cur->outer = nxt;	return cur;}@-The scope can be fixed. This is used by the parser to avoid creation ofa string structure when possible. Subsequently we canreplace the module name in the instructions to become a pointerto the scope directly.Reading a module often calls for opening a scope levelif it didn't exist.@cModule fixModule(Module scope, str nme){	Module s= scope;	if( scopeJump[(int)(*nme)][(int)(*(nme+1))]) 		s= scopeJump[(int)(*nme)][(int)(*(nme+1))];	while(s != NULL){		if( nme == s->name )			return s;		s= s->outer;	}	return newModule(scope, nme);}@-The freeModule operation throws away a symbol withoutconcerns on it whereabouts in the scope structure.This routine therefore assumes care in use.The final action of the system is to remove allinstructions and procedures. This forcefull actionhelps in localization of memory leakages.@cvoid freeSubScope(Module scope){	int i;	if(scope->subscope==0) return;	for(i=0;i<MAXSCOPE;i++)	if( scope->subscope[i]){		freeSymbolList(scope->subscope[i]);		scope->subscope[i]= NULL;	}	GDKfree(scope->subscope);	scope->subscope = 0;}void freeModule(Module m){	Symbol s;	if (m==NULL) return;	if ((s=findSymbolInModule(m, "epilogue")) != NULL) {		InstrPtr pci = getInstrPtr(s->def,0);		if (pci && pci->token == COMMANDsymbol && pci->argc == 1) {			int ret = 0;			(*pci->fcn)(&ret);			(void)ret;		}	}	freeSubScope(m);	clrModuleJump(m->name, m);	GDKfree(m);}void freeModuleList(Module s){	Module t=s;	while(s){		t= s->outer;		s->outer= NULL;		freeModule(s);		s=t;	}}@-After filling in a structure it is added to the multi-levelsymbol table. We keep a skip list of similar named functionsymbols. This speeds up searching provided the modules adhireto the structure group the functions as well.@cvoid insertSymbol(Module scope, Symbol prg){	InstrPtr sig;	int t;	Module c;	sig = getSignature(prg);	if(getModuleId(sig) && getModuleId(sig)!= scope->name){		/* move the definition to the proper place */		c= findModule(scope,getModuleId(sig));		if(c == NULL){			GDKwarning("insertSymbol:undefined module\n");		} else scope = c;	}	t = getSubScope(getFunctionId(sig));	if( scope->subscope == NULL)		newSubScope(scope);	if(scope->subscope[t] == prg){		/* already known, last inserted */	 } else  {		prg->peer= scope->subscope[t];		scope->subscope[t] = prg;		if( prg->peer && 			idcmp(prg->name,prg->peer->name) == 0)			prg->skip = prg->peer->skip;		else			prg->skip = prg->peer;	}	assert(prg != prg->peer);}@-Removal of elements from the symbol table should bedone with care. For, it should be assured thatthere are no references to the definition at themoment of removal. This situation can not easilychecked at runtime, without tremendous overhead.@cvoid deleteSymbol(Module scope, Symbol prg){		InstrPtr sig;		int t;		sig = getSignature(prg);	if( getModuleId(sig) && getModuleId(sig)!= scope->name ){		/* move the definition to the proper place */		Module c= findModule(scope,getModuleId(sig));		if(c == NULL){			GDKwarning("deleteSymbol:undefined module\n");		} else scope = c;	}	t = getSubScope(getFunctionId(sig));	if( scope->subscope[t] == prg){		scope->subscope[t] = scope->subscope[t]->peer;		freeSymbol(prg);	} else {		Symbol nxt = scope->subscope[t];		while( nxt->peer != NULL){			if( nxt->peer == prg){			    nxt->peer = prg->peer;			    nxt->skip = prg->peer;			    freeSymbol(prg);			    return;			}			nxt = nxt->peer;		}		}}@+ InheritanceThe MAL type checker does not apply type inheritance. Such a functionalitycan, however, be readily implemented with a MAL rewriter.An early version of the interpreter contained a simple inheritance scheme,which quickly became too complex to manage properly.The default inheritance sequence is derived from the include order.Most recently modules shield older modules, unless the user has specifiedan explicit module name. This dus not work for dynamically loaded modules,which may cause existing programs to be falsely bound to new implementations.The mechanism to control the inheritance structure consists of three features.First, a module can be excluded from automatic inheritance by setting a flag.This leads to skipping it during function resoluation.The second mechanism is to enforce a partial order among the scopes.The routine setInheritance(F,S) ensures that module F is inspectedbefore module S. In case it does not hold, S is placed just after F.Since the modules are currently shared between all clients,such reshufflings may have drastic side effects.To circumvent this, we have to make a private copy of the Scope chainand the lookup table. [TODO]@cvoid setInheritanceMode(Module m,int flag){	(void) flag;	m->inheritance = 0;}Module setInheritance(Module h, Module f, Module s){	Module fp, sp;	int i=0, j=0;	sp= h;	while(sp->outer && sp->outer->outer !=s) {		sp= s;		i++;	}	fp= h;	while(fp->outer !=f) {		fp= f;		j++;	}	if( j<i) return h;	if(h==s){		h= s->outer; 		s->outer= f->outer;		f->outer=s;	} else {		sp->outer=s->outer;		s->outer = f->outer;		f->outer =s;	}	return h;}@+ Searching the scope structure.Finding a scope is unrestricted. For modules we explicitly look forthe start of a new module scope.All core modules are accessed through the jumptable.The 'user' module is an alias for the scope attachedto the current user.@cModule findModule(Module scope, str name){	Module def=scope;	if( name==NULL) return scope;	scope= scopeJump[(int)(*name)][(int)(*(name+1))];	while(scope != NULL){			if( name == scope->name )					return scope;			scope= scope->sibling;	}	/* default is always matched with current */	if( def->name==NULL) return NULL;	return def;}@-The routine @%findMALSymbol@ starts at the MAL scope level and searches an element amongst the peers. If it fails, it will recursivelyinspect the outer scopes.In principal, external variables are subject to synchronization actionsto avoid concurrency conflicts. This also implies, that any parallelblock introduces a temporary scope.The variation on this routine is to dump the definition ofall matching definitions.@cSymbol findSymbolInModule(Module v, str fcn){	Symbol s;	if( v == NULL || fcn == NULL) return NULL;	s= v->subscope[(int)(*fcn)];	while(s!=NULL){		if( idcmp(s->name,fcn)==0 ) return s;		s= s->skip;	}	return NULL;}Symbol findMALSymbol(str mod, str fcn){	Module v;	v= findModule(mal_scope, getName(mod,strlen(mod)) );	return findSymbolInModule(v,fcn);}int displayModule(stream *f, Module v, str fcn, int listing){	Symbol s;	int k=0;	if( v == NULL || fcn == NULL) return 0;	s= v->subscope[(int)(*fcn)];	while(s!=NULL){		if( idcmp(s->name,fcn)==0 ) {			printFunction(f,s->def,listing);			k++;		}		s= s->peer;	}	return k;}@- Utilities@cvoid  printModuleScope(stream *fd, Module scope, int tab, int outer){	int j;	Module s=scope;	Symbol t;	stream_printf(fd,"%smodule %s", 		(scope->isAtomModule?"atom ":""),s->name);	stream_printf(fd,"\n");	if( s->subscope)	for(j=0;j<MAXSCOPE;j++)	if(s->subscope[j]){		stream_printf(fd,"[%c]",j);		for(t= s->subscope[j];t!=NULL;t=t->peer) {			stream_printf(fd," %s",t->name);			if( getSignature(t)==NULL ||			    (getSignature(t)->fcn==0 &&			     getSignature(t)->token == COMMANDsymbol &&			     getSignature(t)->blk==0) ) 			    stream_printf(fd,"(?)");		}		stream_printf(fd,"\n");	}	stream_printf(fd,"\n");	if(outer && scope->outer) printModuleScope(fd,scope->outer,tab+1, outer);}void showModules(stream *f, Module s){	for(; s; s= s->outer) {		stream_printf(f,"%s",s->name);		if( s== mal_scope) stream_printf(f,"(*)");		if( s->subscope==0) stream_printf(f,"?");		if(s->outer) stream_printf(f,",");	}	stream_printf(f,"\n");}void debugModule(stream *f, Module start, str nme){	Module m;	if( nme==0 || *nme ==0) printModuleScope(f, start,0,TRUE);	else{		char *s;		for(s=nme;*s && (isalnum((int) *s) ||*s=='_');s++);		*s = 0;		m= findModule(start,nme);		if( m== NULL) stream_printf(f,"Module '%s' not found\n",nme);		else printModuleScope(f,m,0,FALSE);	}}@-The commands and operators come with a short description. The dumpManual() command produces a single XML file for post processing and producing a system manual.@cvoid dumpManualHeader(stream *f){	stream_printf(f,"<?xml version=\"1.0\"?>\n");	stream_printf(f,"<manual>\n");}void dumpManualFooter(stream *f){	stream_printf(f,"</manual>\n");}int cmpModName(Module *f, Module *l){	return strcmp((*f)->name, (*l)->name);}int cmpFcnName(InstrPtr f, InstrPtr l){	if(getFunctionId(f) && getFunctionId(l))		return strcmp(getFunctionId(f), getFunctionId(l));	return 0;}void dumpManual(stream *f, Module s, int recursive){	int j;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -