main() { char s[] = "a"; char c; int hash, box, minblocks; int period=HOURLY-1; char *boxes[HOURLY]; for (c=0; c<HOURLY; c++) { boxes[c] = 0; } for (c='a';c <='z'; c++){ *s = c; // The block algorithm is copied from evalfunction.c hash=OatHash(s); box = (int)(0.5 + period*hash/(double)CF_HASHTABLESIZE); minblocks = box % HOURLY; // Back to original code if (!boxes[minblocks]) { boxes[minblocks] = strncpy((char *)malloc(2),s,2); } } printf(" \"ok\" xor => {\n"); for (c=0; c<HOURLY; c++) { printf("\tsplayclass(\"%s\",\"hourly\"), # Box %d\n", boxes[c], c); } printf("\t};\n"); }
main() { char s[] = "xx"; char c,c2; int hash, box, minblocks; int period=DAILY-1; char *boxes[DAILY]; for (box=0; box<DAILY; box++) { boxes[box] = 0; } for (c='A';c <='z'; c++){ for (c2='A';c2 <='z'; c2++){ if (!(isalnum(c) && isalnum(c2))) continue; s[0] = c; s[1] = c2; // The block algorithm is copied from evalfunction.c hash=OatHash(s); box = (int)(0.5 + period*hash/(double)CF_HASHTABLESIZE); // Back to original code if (!boxes[box]) { boxes[box] = strncpy((char *)malloc(3),s,3); } } } printf(" \"ok\" xor => {\n"); for (box=0; box<DAILY; box++) { printf("\tsplayclass(\"%s\",\"daily\"), # Box %d\n", boxes[box], box); } printf("\t};\n"); }
static int EvalClassExpression(EvalContext *ctx, Constraint *cp, Promise *pp) { int result_and = true; int result_or = false; int result_xor = 0; int result = 0, total = 0; char buffer[CF_MAXVARSIZE]; Rlist *rp; FnCall *fp; Rval rval; if (cp == NULL) { Log(LOG_LEVEL_ERR, "EvalClassExpression internal diagnostic discovered an ill-formed condition"); } if (!IsDefinedClass(ctx, pp->classes, PromiseGetNamespace(pp))) { return false; } if (EvalContextPromiseIsDone(ctx, pp)) { return false; } if (IsDefinedClass(ctx, pp->promiser, PromiseGetNamespace(pp))) { if (PromiseGetConstraintAsInt(ctx, "persistence", pp) == 0) { Log(LOG_LEVEL_VERBOSE, " ?> Cancelling cached persistent class %s", pp->promiser); EvalContextHeapPersistentRemove(pp->promiser); } return false; } switch (cp->rval.type) { case RVAL_TYPE_FNCALL: fp = (FnCall *) cp->rval.item; /* Special expansion of functions for control, best effort only */ FnCallResult res = FnCallEvaluate(ctx, fp, pp); FnCallDestroy(fp); cp->rval = res.rval; break; case RVAL_TYPE_LIST: for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next) { rval = EvaluateFinalRval(ctx, "this", (Rval) {rp->item, rp->type}, true, pp); RvalDestroy((Rval) {rp->item, rp->type}); rp->item = rval.item; rp->type = rval.type; } break; default: rval = ExpandPrivateRval(ctx, "this", cp->rval); RvalDestroy(cp->rval); cp->rval = rval; break; } if (strcmp(cp->lval, "expression") == 0) { if (cp->rval.type != RVAL_TYPE_SCALAR) { return false; } if (IsDefinedClass(ctx, (char *) cp->rval.item, PromiseGetNamespace(pp))) { return true; } else { return false; } } if (strcmp(cp->lval, "not") == 0) { if (cp->rval.type != RVAL_TYPE_SCALAR) { return false; } if (IsDefinedClass(ctx, (char *) cp->rval.item, PromiseGetNamespace(pp))) { return false; } else { return true; } } // Class selection if (strcmp(cp->lval, "select_class") == 0) { char splay[CF_MAXVARSIZE]; int i, n; double hash; total = 0; for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next) { total++; } if (total == 0) { Log(LOG_LEVEL_ERR, "No classes to select on RHS"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } snprintf(splay, CF_MAXVARSIZE, "%s+%s+%ju", VFQNAME, VIPADDRESS, (uintmax_t)getuid()); hash = (double) OatHash(splay, CF_HASHTABLESIZE); n = (int) (total * hash / (double) CF_HASHTABLESIZE); for (rp = (Rlist *) cp->rval.item, i = 0; rp != NULL; rp = rp->next, i++) { if (i == n) { EvalContextHeapAddSoft(ctx, rp->item, PromiseGetNamespace(pp)); return true; } } } /* If we get here, anything remaining on the RHS must be a clist */ if (cp->rval.type != RVAL_TYPE_LIST) { Log(LOG_LEVEL_ERR, "RHS of promise body attribute '%s' is not a list", cp->lval); PromiseRef(LOG_LEVEL_ERR, pp); return true; } // Class distributions if (strcmp(cp->lval, "dist") == 0) { for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next) { result = IntFromString(rp->item); if (result < 0) { Log(LOG_LEVEL_ERR, "Non-positive integer in class distribution"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } total += result; } if (total == 0) { Log(LOG_LEVEL_ERR, "An empty distribution was specified on RHS"); PromiseRef(LOG_LEVEL_ERR, pp); return false; } double fluct = drand48(); double cum = 0.0; for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next) { double prob = ((double) IntFromString(rp->item)) / ((double) total); cum += prob; if (fluct < cum) { break; } } snprintf(buffer, CF_MAXVARSIZE - 1, "%s_%s", pp->promiser, (char *) rp->item); /* FIXME: figure why explicit mark and get rid of it */ EvalContextMarkPromiseDone(ctx, pp); if (strcmp(PromiseGetBundle(pp)->type, "common") == 0) { EvalContextHeapAddSoft(ctx, buffer, PromiseGetNamespace(pp)); } else { EvalContextStackFrameAddSoft(ctx, buffer); } return true; } /* and/or/xor expressions */ for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next) { if (rp->type != RVAL_TYPE_SCALAR) { return false; } result = IsDefinedClass(ctx, (char *) (rp->item), PromiseGetNamespace(pp)); result_and = result_and && result; result_or = result_or || result; result_xor ^= result; } // Class combinations if (strcmp(cp->lval, "or") == 0) { return result_or; } if (strcmp(cp->lval, "xor") == 0) { return (result_xor == 1) ? true : false; } if (strcmp(cp->lval, "and") == 0) { return result_and; } return false; }
int GetHash(const char *name) { return OatHash(name); }
static void TestHashEntropy(char *names, char *title) { char word[32], *sp; int i, j, slot, eslot, sslot, hashtable[CF_HASHTABLESIZE], ehashtable[CF_HASHTABLESIZE], shashtable[CF_HASHTABLESIZE]; int freq[10], efreq[10], sfreq[10]; double tot = 0, etot = 0, stot = 0; for (i = 0; i < CF_HASHTABLESIZE; i++) { hashtable[i] = 0; ehashtable[i] = 0; shashtable[i] = 0; } printf(" -> Trial of \"%s\":\n", title); for (i = 0, sp = names; *sp != '\0'; sp += strlen(word) + 1, i++) { struct timespec start, stop; word[0] = '\0'; sscanf(sp, "%s", word); if (word[0] == '\0') { break; } clock_gettime(CLOCK_REALTIME, &start); slot = RefHash(word); clock_gettime(CLOCK_REALTIME, &stop); tot += (double) (stop.tv_sec - start.tv_sec) + (double) (stop.tv_nsec - start.tv_nsec); clock_gettime(CLOCK_REALTIME, &start); eslot = ElfHash(word); clock_gettime(CLOCK_REALTIME, &stop); etot += (double) (stop.tv_sec - start.tv_sec) + (double) (stop.tv_nsec - start.tv_nsec); clock_gettime(CLOCK_REALTIME, &start); sslot = OatHash(word); clock_gettime(CLOCK_REALTIME, &stop); stot += (double) (stop.tv_sec - start.tv_sec) + (double) (stop.tv_nsec - start.tv_nsec); hashtable[slot]++; ehashtable[eslot]++; shashtable[sslot]++; printf("SLOTS: %d,%d,%d\n", slot, eslot, sslot); } printf("reference time %lf\n", tot / (double) CF_BILLION); printf("elf time %lf\n", etot / (double) CF_BILLION); printf("fast time %lf\n", stot / (double) CF_BILLION); printf(" -> Hashed %d %s words into %d slots with the following spectra:\n", i, title, CF_HASHTABLESIZE); for (j = 0; j < 10; j++) { freq[j] = efreq[j] = sfreq[j] = 0; } for (i = 0; i < CF_HASHTABLESIZE; i++) { for (j = 0; j < 10; j++) { if (hashtable[i] == j) { freq[j]++; } if (ehashtable[i] == j) { efreq[j]++; } if (shashtable[i] == j) { sfreq[j]++; } } } printf("\n"); for (j = 1; j < 10; j++) { if (freq[j] > 0) { printf(" -> F[%d] = %d\n", j, freq[j]); } } printf("\n"); for (j = 1; j < 10; j++) { if (efreq[j] > 0) { printf(" -> eF[%d] = %d\n", j, efreq[j]); } } printf("\n"); for (j = 1; j < 10; j++) { if (sfreq[j] > 0) { printf(" -> sF[%d] = %d\n", j, sfreq[j]); } } }
static double GetSplay(void) { char splay[CF_BUFSIZE]; snprintf(splay, CF_BUFSIZE, "%s+%s+%ju", VFQNAME, VIPADDRESS, (uintmax_t)getuid()); return ((double) OatHash(splay, CF_HASHTABLESIZE)) / CF_HASHTABLESIZE; }