V10/ipc/mgrs/ns/tuple.c
#include <libc.h>
#include <fio.h>
#include <string.h>
#include "dbtypes.h"
/*
* free a tuple and all the attributes making it up
*/
Tuple::~Tuple()
{
register Attribute *ap, *nap;
for(ap=first; ap; ap=nap){
nap = ap->next;
delete ap;
}
}
/*
* Parse a list of attributes and add the attributes to this tuple.
* If o is non-zero add each attribute to that ordered list.
*/
Tuple::Tuple(char *str, Ordered *o, Tuple **alist, char wildcard)
{
char *attributes[MAXPAIRS];
int i, n;
first = last = (Attribute *)0;
tail = (Tuple *)0;
/*
* parse and create the tuple
*/
setfields(" \t\n");
n = getmfields(str, attributes, MAXPAIRS);
for(i=0; i<n; i++){
if(*attributes[i]=='\0')
break;
if(first==(Attribute *)0)
first = last =new Attribute(attributes[i], this, wildcard);
else {
last->next = new Attribute(attributes[i], this, wildcard);
last = last->next;
}
/*
* insert each attribute into an ordered list
*/
if(o)
last->insert(o);
}
/*
* chain into an allocation list for later deallocation
*/
if(alist){
anext = *alist;
*alist = this;
}
}
/*
* concatenate two tuples
*/
void
Tuple::cat(Tuple *ntail)
{
tail = ntail;
}
/*
* Calculate the distance of this tuple from some other tuple. The
* distance measure is the minimum of the distances between all of this
* tuple's attributes and all of the origin's.
*/
void
Tuple::distance(Tuple *origin)
{
Attribute *o;
Attribute *p;
Tuple *t;
int ndist;
dist = MAXDISTANCE;
for(t=this; t; t=t->tail){
for(p=t->first; p; p=p->next){
for(o=origin->first; o; o=o->next){
ndist = p->distance(o);
if(ndist<dist) {
dist = ndist;
}
}
}
}
}
/*
* Return 0 if the tuple doesn't match the pattern, non-zero otherwise.
*/
Tuple::match(Tuple *pattern)
{
Attribute *p;
Attribute *me;
Tuple *t;
for(p=pattern->first; p; p=p->next){
/*
* each tuple can be a list of tuples
*/
for(t=this; t; t=t->tail){
for(me=t->first; me; me=me->next){
if(me->compare(p)==0)
break;
}
if(me)
break;
}
if(me==(Attribute *)0)
return 0;
}
return 1;
}
/*
* output a linear version of the tuple on fd
*/
int
Tuple::print(int fd)
{
Attribute *p;
Tuple *t;
for(t=this; t; t=t->tail){
for(p=t->first; p; p=p->next){
if (p->simpleprint(fd) < 0)
return -1;
}
}
return 0;
}
/*
* Free a list of tuples
*/
void
freetuplelist(Tuple **list)
{
Tuple *t, *nt;
if(*list==(Tuple *)0)
return;
for(t=*list; t; t=nt){
nt = t->anext;
delete t;
}
*list = (Tuple *)0;
}
/*
* Lookup a tuple in an ordered list. Return the set of matches.
*/
Set *
lookup(char *ks, Ordered *o)
{
Tuple *kt;
Attribute *a;
Set *s=0;
/*
* parse the key
*/
kt = new Tuple(ks, '*');
/*
* Using first attribute as the primary key, find the first
* attribute in the ordered list that matches.
*/
a = (Attribute *)kt->first->search(o);
/*
* while the next attribute in the ordered list
* matches the search key, check the rest of the
* attributes for a match
*/
while(a && a->compatible(kt->first)) {
if(a->tuple->match(kt)){
/*
* add each matching tuple to the
* set to be returned
*/
if(s==(Set*)0)
s = new Set;
s->add(a->tuple);
}
a = (Attribute *)a->succ();
}
delete kt;
return s;
}
/*
* Print the value of the first attribute matching type. Return 0 if a value
* is printed.
*/
int
Tuple::printvalue(int fd, char *type)
{
Tuple *t;
Attribute *a;
for(t=this; t; t=t->tail)
for(a=t->first; a; a=a->next)
if(a->printvalue(fd, type)==0)
return 0;
return -1;
}