V10/ipc/mgrs/ns/tuple.c

Compare this file to the similar file:
Show the results in this format:

#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;
}