/* $Id: acesybase.c,v 1.3 1999/09/01 11:25:03 fw Exp $ */ /* File: acesybase.c * Author: Detlef Wolf * Copyright (C) J Thierry-Mieg and Detlef Wolf, 1994 * ------------------------------------------------------------------- * Acedb is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (MRC LMB, UK) rd@mrc-lmb.cam.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * * Description: translated between ACEDB tree and acesyb representation * Exported functions: sybaseInit sybaseKill sybaseGet sybaseCommit sybaseStore * HISTORY: * Last edited: Sep 1 14:20 1994 (srk) * Created: Fri Oct 18 20:25:36 1991 (mieg) *------------------------------------------------------------------- */ #include #include "acedb.h" #include "acesybase.h" #include "pick.h" #include "lex_bl_.h" #include "bs_.h" #include "chrono.h" #include "acesyb.h" #include "systags.h" /* #define CHRONO */ /* --------------------- module memory ---------------------------- */ static int currentNodeNo; /* used in tree2array */ static KEY currentKey; /* global for efficiency */ static baseNode; /* index of the the first node of the current object */ static KEY lastTag; /* number of last tag converted */ static int valPos; /* position after a tag */ static Array nodeBuf; /* I/O buffer */ static int acesybaseTrace=0; /* trace level, 0=none */ /* --------------------- local functions ---------------------------- */ /* --------------------------------------------------------------- */ static void sybasePrintRec(BS bs, int offset) { /* recursively descend into the tree, right before down */ int i; int l=0; /* number of chars printed */ printf(" %d/%d(%s)", class(bs->key), KEYKEY(bs->key), bsText(bs)); l+=10+1; if (bs->right != NULL) sybasePrintRec(bs->right, offset+l); if (bs->down != NULL) { printf("\n"); for (i=1;i<=offset;i++) printf(" "); sybasePrintRec(bs->down, offset); }; } /* notes on bs_.h, that declares the cell data structure bshow.key -- tells the type of cell: 0 .. _LastN : a data cell (Int, Float, Text); n.x holds data I accept only _Int, _Float and _Text _LastN .. 2^24-1 : a tag; n is not relevant 2^24 .. 2^32-1 : a pointer; n.key is redunant but I fill it anyway my comments on the code: typedef union { int i; unsigned int u; -- not used long L; -- not used unsigned long U; -- not used float f; mytime_t time ; TEXTKEY text; -- not used KEY key ; -- not used, but I fill it } BSdata; typedef struct bshow *BS; typedef struct btext *BT; struct bshow {BS up, down, right; KEY key; -- type/tagNo/Pointer BSdata n; -- data depending on key BT bt ; -- textdata (should be in BSdata, strange design) -- bt is not allocated by BSalloc int size; } ; struct btext { char *cp ; BS bsm ; only used during treedisp update } ; */ /* --------------------------------------------------------------- */ static void bs2node (BS bs, ayNodeType *np) { /* data conversion from ACEDB tree cell into acesyb node text data: since it do not know, whether the caller will still need them, I allocate new memory and make a copy precondition: valPos is set postcondition: lastTag is set valPos is set */ if (bsIsTag(bs)) { /* just a tag, translated to a boolean */ np->dataType=AY_BOOL; lastTag= (np->data.boolData=KEYKEY(bs->key)); valPos=0; /* new tag starts */ } else { valPos++; if (class(bs->key)) { /* a pointer */ np->dataType=AY_KEY; np->data.keyData=bs->key; } else { /* must be a simple data type */ switch (KEYKEY(bs->key)) { case _Int: np->dataType=AY_INT; np->data.intData=bs->n.i; break; case _Float: np->dataType=AY_FLOAT; np->data.floatData=bs->n.f;break; case _Text: np->dataType=AY_TEXT; np->data.textData=messalloc(strlen(bs->bt->cp)); strcpy(np->data.textData, bs->bt->cp); break; case _DateType: np->dataType=AY_DATE; np->data.dateData=bs->n.time; break; default: messcrash("bs2node: unknown data type %d", KEYKEY(bs->key)); } /* switch */ }; /* simple data type */ } /* not a tag */ }; /* --------------------------------------------------------------- */ static void node2bs (ayNodeType *np, BS bs) { /* data conversion from acesyb node into ACEDB tree cell text data: since I assume that the current contents of the node buffer is discarded anyway, I give the text memory of the node as a present to the tree and zero the pointer in the node. */ switch (np->dataType) { /* case AY_EMPTY: printf("AY_EMPTY\n"); break; */ case AY_INT : bs->key=_Int; bs->n.i=np->data.intData; break; case AY_FLOAT: bs->key=_Float; bs->n.f=np->data.floatData; break; case AY_TEXT : bs->key=_Text; bs->bt = BTalloc(); bs->bt->cp=np->data.textData; np->data.textData=NULL; /* steal the memory */ break; case AY_BOOL : bs->key=np->data.boolData; break; case AY_KEY : bs->key=np->data.keyData; bs->n.key=np->data.keyData; /* necessary? */ break; case AY_DATE : bs->key=_DateType; bs->n.time=np->data.dateData; break; default : messcrash("node2bs: invalid data type %d",np->dataType); }; }; /* --------------------------------------------------------------- */ static void tree2array (BS bs) { /* convert an ACEDB tree into an acesyb array precondition: currentNodeNo contains the index of the node to be generated; currentKey contains the key of the current ACEDB object postcondition: (after last return) nodeBuf is filled with contents of bs algo: the father creates its children, so he knows them and can point to them */ ayNodeType *node=arrayp(nodeBuf, arrayMax(nodeBuf), ayNodeType); node->key=currentKey; node->thisNode=currentNodeNo; node->rightNode=NULL; node->downNode=NULL; bs2node(bs, node); /* convert simple data */ node->classNo=class(currentKey); node->tagNo=lastTag; /* should get no of last tag converted by bs2node */ node->valPos=valPos; /* set by bs2node */ if (bs->right) { node->rightNode=++currentNodeNo; tree2array(bs->right); }; if (bs->down) { node->downNode=++currentNodeNo; tree2array(bs->down); }; } /* --------------------------------------------------------------- */ static void array2tree (int nno, BS bs) { /* convert an acesyb array into an ACEDB tree input: nno -- index in nodeBuf of node to convert, bs -- pointer to receiving cell precondition: nodeBuf is corrently wired baseNode contains the index of the first node of the current object postcondition: (after last return) the tree is attached to bs algo: the father creates its children, so he knows them and can point to them */ ayNodeType *np=arrp(nodeBuf, baseNode+nno, ayNodeType); bs->right=NULL; bs->down=NULL; bs->key=np->key; node2bs(np, bs); /* convert simple data */ if (np->rightNode) { BS son=BSalloc(); /* all elements are filled with zeros */ son->up=bs; /* make the son point to his father */ bs->right=son; array2tree(np->rightNode, son); }; if (np->downNode) { BS son=BSalloc(); son->up=bs; /* make the son point upward to his father */ bs->down=son; array2tree(np->downNode, son); }; } /* --------------------- exported functions ---------------------------- */ /* --------------------------------------------------------------- */ void sybaseInit (void) { if (getenv("ACESYBASE_TRACE")) { sscanf(getenv("ACESYBASE_TRACE"),"%d",&acesybaseTrace); printf("sybaseInit: trace level set to %d\n", acesybaseTrace); }; nodeBuf=arrayReCreate(nodeBuf, 128, ayNodeType); baseNode=0; /* assume: only one object at a time */ ayBegin(); } /* --------------------------------------------------------------- */ void sybaseKill (KEY key) { LEXP q; ayNodeType *np; chrono("SybaseKill") ; q=KEY2LEX(key); if(q->diskaddr != 0) { q->diskaddr = 0 ; /* reset faked disk address */ lexmark(class(key)); } if (acesybaseTrace) printf("sybaseKill: key=%d/%d", class(key), KEYKEY(key)); ayFreeNodeBuf(nodeBuf); np=arrayp(nodeBuf, 0, ayNodeType); np->key=key; np->thisNode=0; if (ayDelete(nodeBuf)) messcrash("sybaseKill: could not find key=%d/%d", class(key), KEYKEY(key)); chronoReturn () ; return ; } /* --------------------------------------------------------------- */ BS sybaseGet (KEY key) { ayQueryType query; BS bs = BSalloc(); if (acesybaseTrace) printf("sybaseGet: key=%d/%d\n", class(key), KEYKEY(key)); query.mask.key=key; ayRead(nodeBuf, &query); if (!arrayMax(nodeBuf)) messcrash("sybaseGet: key=%d not found", key); bs->up = NULL; /* mark this to be the root */ array2tree (0, bs); if (acesybaseTrace>1) { printf("bsTreeGet: "); sybasePrint(bs); }; if (bs->key != key) messcrash("sybaseGet: requested key %d, but got %d", key, bs->key); return bs ; } /* --------------------------------------------------------------- */ void sybaseCommit() { ayEnd(1); } /* --------------------------------------------------------------- */ void sybaseStore (BS bs) { KEY key = bs->key ; LEXP q; chrono("bsTreeSybaseStore") ; if (acesybaseTrace) printf("sybaseStore: key=%d/%d, %d\n", class(key), KEYKEY(key), key); if (acesybaseTrace>1) { printf("sybaseStore:"); sybasePrint(bs); }; q=KEY2LEX(key); if(q->diskaddr != 1) /* fake a disk address */ { q->diskaddr = 1; lexmark(class(key)); } currentNodeNo=0; /* initialize tree2array */ lastTag=0; valPos=0; currentKey=key; /* store here for efficient passing to tree2array */ ayFreeNodeBuf(nodeBuf); /* initialize receiving array */ tree2array(bs); /* result is in nodeBuf */ ayWrite(nodeBuf); chronoReturn(); return ; } /* --------------------------------------------------------------- */ void sybasePrint(BS bs) { printf("--------tree %d/%d\n", class(bs->key), KEYKEY(bs->key)); if (bs->down) printf("PROBLEM: root cell has down pointer\n"); if (bs->right) sybasePrintRec(bs->right,1); printf("\n"); }