4 #include <TupleSchema.h>
7 * This callback function returns the hashcode of a key.
9 * \param this is a pointer to the ItemKeyFun record from where this
10 * callback got invoked
12 * \param key is the key to produce a hascode for
14 * \returns the hashcode which is a VectorIndex (i.e. unsigned long)
16 * The hashcode is used for indexing into the backing Vector for
17 * finding the an item via its key. The same key must map consistently
18 * to the same hashcode while the hashtable contains an item with that
19 * key. Different keys map map to the same hashcode, in which case the
20 * Vector placement is made at the first empty or hole slot following
23 static unsigned long TupleSchema_hashcode(void *this,void *key) {
24 TupleSchema *def = (TupleSchema *) this;
25 ItemKeyFun **columns = (ItemKeyFun**) def->columns->elements;
26 Tuple *kp = (Tuple*) key;
28 unsigned long value = 5381;
29 for ( ; i < def->columns->size; i++ ) {
32 if ( kp->elements[i] ) {
33 value += columns[i]->hashcode( columns[i], kp->elements[i] );
42 * This callback function determines whether an item has a
45 static int TupleSchema_haskey(void *this,void *item,void *key) {
46 TupleSchema *def = (TupleSchema *) this;
47 ItemKeyFun **columns = (ItemKeyFun**) def->columns->elements;
48 Tuple *kp = (Tuple*) key;
49 Tuple *tp = (Tuple*) item;
51 for ( ; i < def->columns->size; i++ ) {
52 if ( columns[i] && kp->elements[i] ) {
53 if ( columns[i]->haskey(
54 columns[i], tp->elements[i], kp->elements[i] ) == 0 ) {
64 * This callback function returns the key of an item by considering
67 static void *TupleSchema_itemkey(void *this,void *item) {
68 TupleSchema *def = (TupleSchema *) this;
69 ItemKeyFun **columns = (ItemKeyFun**) def->columns->elements;
70 Tuple *tp = (Tuple*) item;
71 Tuple *key = Tuple_clone( tp );
73 for ( i = 0; i < def->columns->size; i++ ) {
75 key->elements[i] = columns[i]->itemkey(
76 columns[i], tp->elements[i] );
85 * This callback function handles a key obtained from the itemkey
86 * callback function to reclaim temporary allocation.
88 static void TupleSchema_releasekey(void *this,void *key) {
89 TupleSchema *def = (TupleSchema *) this;
90 ItemKeyFun **columns = (ItemKeyFun**) def->columns->elements;
91 Tuple *kp = (Tuple*) key;
93 for ( i = 0; i < def->columns->size; i++ ) {
95 columns[i]->releasekey( columns[i], kp->elements[i] );
101 #define OUT(X) a = X; if ( a > limit ) return 0; buffer += a; limit -= a
104 * This callback function writes a representation of an item into
105 * a character buffer.
107 static int TupleSchema_tostring(void *this,void *item,char *buffer,int limit) {
108 TupleSchema *def = (TupleSchema *) this;
109 ItemKeyFun **columns = (ItemKeyFun**) def->columns->elements;
110 Tuple *t = (Tuple*) item;
113 for ( i = 0; i < def->columns->size; i++ ) {
114 OUT( snprintf( buffer, limit, x ) );
116 OUT( columns[i]->tostring(
117 columns[i], t->elements[i], buffer, limit ) );
119 OUT( snprintf( buffer, limit, ">" ) );
123 ItemKeyFun TupleSchema_callbacks = {
124 .hashcode = TupleSchema_hashcode,
125 .haskey = TupleSchema_haskey,
126 .itemkey = TupleSchema_itemkey,
127 .releasekey = TupleSchema_releasekey,
128 .tostring = TupleSchema_tostring
131 TupleSchema *TupleSchema_create(Tuple *columns) {
132 TupleSchema *ts = (TupleSchema*) malloc( sizeof( TupleSchema ) );
133 (*ts) = (TupleSchema) {
134 .base = TupleSchema_callbacks,
140 #define COPYA(T,P,N) (T*) memcpy( malloc( N * sizeof(T) ), P, N * sizeof( T ) )
141 #define COPY(T,P) COPYA(T,P,1)
143 // Duplicate a TupleSchema with optionally some columns reset.
144 TupleSchema *TupleSchema_mask(TupleSchema *schema,...) {
145 TupleSchema *masked = COPY(TupleSchema,schema);
146 masked->columns = Tuple_clone( schema->columns );
149 va_start( ap, schema );
151 i = va_arg( ap, int );
152 if ( i < 0 || i >= schema->columns->size ) {
155 masked->columns->elements[i] = 0;