-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtuple.c
More file actions
135 lines (115 loc) · 2.87 KB
/
Copy pathtuple.c
File metadata and controls
135 lines (115 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// tuple.c ... functions on tuples
// part of Multi-attribute Linear-hashed Files
// Last modified by John Shepherd, July 2019
#include "defs.h"
#include "tuple.h"
#include "reln.h"
#include "hash.h"
#include "chvec.h"
#include "bits.h"
// return number of bytes/chars in a tuple
int tupLength(Tuple t)
{
return strlen(t);
}
// reads/parses next tuple in input
Tuple readTuple(Reln r, FILE *in)
{
char line[MAXTUPLEN];
if (fgets(line, MAXTUPLEN-1, in) == NULL)
return NULL;
line[strlen(line)-1] = '\0';
// count fields
// cheap'n'nasty parsing
char *c; int nf = 1;
for (c = line; *c != '\0'; c++)
if (*c == ',') nf++;
// invalid tuple
if (nf != nattrs(r)) return NULL;
return copyString(line); // needs to be free'd sometime
}
// extract values into an array of strings
void tupleVals(Tuple t, char **vals)
{
char *c = t, *c0 = t;
int i = 0;
for (;;) {
while (*c != ',' && *c != '\0') c++;
if (*c == '\0') {
// end of tuple; add last field to vals
vals[i++] = copyString(c0);
break;
}
else {
// end of next field; add to vals
*c = '\0';
vals[i++] = copyString(c0);
*c = ',';
c++; c0 = c;
}
}
}
// release memory used for separate attirubte values
void freeVals(char **vals, int nattrs)
{
int i;
for (i = 0; i < nattrs; i++) free(vals[i]);
}
// hash a tuple using the choice vector
// TODO: actually use the choice vector to make the hash
// MA hash algorithm adapted from lecture notes
Bits tupleHash(Reln r, Tuple t)
{
char buf[MAXBITS+1];
Count nvals = nattrs(r);
char **vals = malloc(nvals*sizeof(char *));
assert(vals != NULL);
tupleVals(t, vals);
Bits hashes[nvals];
Bits attriHash;
Bits hash = 0;
ChVecItem *cv = chvec(r);
int i = 0;
for (i = 0; i < nvals; i++){
hashes[i] = hash_any((unsigned char *)vals[i],strlen(vals[i]));
//bitsString(hashes[nvals],buf);
//printf("hashes(%s) = %s\n", vals[i], buf);
}
//printf("\n\n");
for (i = 0; i < 32; i++){
// for pos i in chvec, grab the r->cv[i].att'th hash
attriHash = hashes[cv[i].att];
//bitsString(attriHash,buf);
//printf("Using attribute num %d, which has hash %s\n", cv[i].att, buf);
if (bitIsSet(attriHash, cv[i].bit)){
hash = setBit(hash, i);
}
}
bitsString(hash,buf);
printf("hash(%s) = %s\n", vals[0], buf);
return hash;
}
// compare two tuples (allowing for "unknown" values)
Bool tupleMatch(Reln r, Tuple t1, Tuple t2)
{
Count na = nattrs(r);
char **v1 = malloc(na*sizeof(char *));
tupleVals(t1, v1);
char **v2 = malloc(na*sizeof(char *));
tupleVals(t2, v2);
Bool match = TRUE;
int i;
for (i = 0; i < na; i++) {
// assumes no real attribute values start with '?'
if (v1[i][0] == '?' || v2[i][0] == '?') continue;
if (strcmp(v1[i],v2[i]) == 0) continue;
match = FALSE;
}
freeVals(v1,na); freeVals(v2,na);
return match;
}
// puts printable version of tuple in user-supplied buffer
void tupleString(Tuple t, char *buf)
{
strcpy(buf,t);
}