static void * go( void * arg) { lladdIterator_t * it = (lladdIterator_t *) arg; pthread_mutex_lock(&mutex); pthread_mutex_unlock(&mutex); int itRet = 0; while((itRet = Titerator_next(-1, it))) { byte * key, * value; int keySize, valueSize; keySize = Titerator_key (-1, it, &key); valueSize = Titerator_value(-1, it, &value); assert(keySize == sizeof(lsn_t)); LogEntry * e = (LogEntry*)value; linearHash_remove_arg * arg = (linearHash_remove_arg*)stasis_log_entry_update_args_ptr(e); assert(arg->keySize == sizeof(lsn_t)); assert(arg->valueSize == sizeof(char)); lsn_t i = *(lsn_t*)(arg+1); array[i]++; assert(array[i] == 1); Titerator_tupleDone(-1, it); } Titerator_close(-1, it); return NULL; }
static void * go2( void * arg) { lladdIterator_t * it = (lladdIterator_t *) arg; pthread_mutex_lock(&mutex); pthread_mutex_unlock(&mutex); int itRet = 0; while((itRet = Titerator_next(-1, it))) { lladdFifo_t ** dirtyFifo_ptr; lladdFifo_t *** bdirtyFifo_ptr = &dirtyFifo_ptr; lladdFifo_t * dirtyFifo; int dirtyFifoSize = Titerator_value(-1, it, (byte**)bdirtyFifo_ptr); dirtyFifo = * dirtyFifo_ptr; assert(dirtyFifo->iterator->type >= 0 && dirtyFifo->iterator->type < MAX_ITERATOR_TYPES); Titerator_tupleDone(-1, it); assert(dirtyFifoSize == sizeof(lladdFifo_t *)); assert(dirtyFifo->iterator->type >= 0 && dirtyFifo->iterator->type < MAX_ITERATOR_TYPES); trygo(dirtyFifo->iterator); } return NULL; }
/* int executeInsert(int xid, recordid tables, char * insert) { char * linecopy = strdup(insert+strlen("insert")); char * strtoks; char * tbl = strtok_r(linecopy," ",&strtoks); char * tup = strtok_r(NULL,"\r\n",&strtoks); if((!tbl) || (!tup)) { printf("parse error\n"); return 0; } char * tupcopy = strdup(tup); char * key = strtok_r(tupcopy,",",&strtoks); char * trunctup = strtok_r(NULL,"\r\n",&strtoks); char * table; if(!trunctup) { trunctup = ""; } int sz = ThashLookup(xid, tables, (byte*)tbl, strlen(tbl)+1, (byte**)&table); if(sz == -1) { printf("Unknown table %s\n", tbl); return 0; } else { assert(sz == strlen((char*)table)+1); recordid tableRid = ridTpl(table); //XXX if(debug) { printf("inserted %s=%s into %s\n", key, tup, tbl); } ThashInsert(xid, tableRid, (byte*)key, strlen(key)+1,(byte*)trunctup,strlen(trunctup)+1); } free(tupcopy); free(linecopy); return 1; } int executeDelete(int xid, recordid tables, char * delete) { char * linecopy = strdup(delete+strlen("delete")); char * strtoks; char * tbl = strtok_r(linecopy," ",&strtoks); char * tup = strtok_r(NULL,"\r\n",&strtoks); if((!tbl) || (!tup)) { printf("parse error\n"); return 0; } char * table; char * tupcopy = strdup(tup); char * key = strtok_r(tupcopy,",",&strtoks); int sz = ThashLookup(xid, tables, (byte*)tbl, strlen(tbl)+1, (byte**)&table); if(sz == -1) { printf("Unknown table %s\n", tbl); return 0; } else { assert(sz == strlen((char*)table)+1); recordid tableRid = ridTpl(table); // if(debug) { printf("deleted ->%s<- from %s\n", key, tbl); ThashRemove(xid, tableRid, (byte*)key, strlen(key)+1);//,(byte*)trunctup,strlen(trunctup)+1); } free(tupcopy); free(linecopy); return 1; } */ static recordid ReferentialDML_lookupTableRid(int xid, ReferentialAlgebra_context_t*context, char * tablename) { expr_list * results = 0; char * line; int err = asprintf(&line, "query {p ($1,$2,$3) {s ($0=\"%s\") TABLES} }", tablename); assert(err != -1); //XXX memory leak! parse(line,&results); assert(results); //XXX assert(results->count == 1); //XXX lladdIterator_t * it = ReferentialAlgebra_ExecuteQuery(xid, context, results->ents[0]->u.q); recordid tableRid; if(it) { int first = 1; while(Titerator_next(xid,it)) { assert(first); first = 0; byte * tup; Titerator_value(xid, it, &tup); tableRid = ridTuple(*(tuple_t*)tup); } Titerator_close(xid, it); } else { abort(); //XXX } return tableRid; }
/** Take two iterators, and make sure they represent the same set. */ static void iterator_test(int xid, lladdIterator_t * reference_impl, lladdIterator_t * tested_impl) { pblHashTable_t * hash = pblHtCreate(); int numEntries = 0; while(Titerator_next(xid, reference_impl)) { int keySize, valSize; byte *key, *val, *valScratch; keySize = Titerator_key(xid, reference_impl, &key); valSize = Titerator_value(xid, reference_impl, &valScratch); val = stasis_malloc(valSize, byte); memcpy(val, valScratch, valSize); // pblHtInsert stores values a pointers to application managed memory. pblHtInsert(hash, key, keySize, val); numEntries ++; } while(Titerator_next(xid, tested_impl)) { numEntries --; int keySize, valSize; byte *key, *val, *valScratch; keySize = Titerator_key(xid, tested_impl, &key); valSize = Titerator_value(xid, tested_impl, &valScratch); val = pblHtLookup(hash, key, keySize); assert(val); assert(!memcmp(val, valScratch, valSize)); free(val); pblHtRemove(hash, key, keySize); } assert(!numEntries); }
JNIEXPORT jboolean JNICALL Java_stasis_jni_Stasis_iterator_1next (JNIEnv *e, jclass c, jlong xid, jbyteArray jbait) { size_t sz; lladdIterator_t** it = (lladdIterator_t**)bytes_jbyteArray(e,jbait,&sz); return (jboolean)Titerator_next((int)xid, *it); }
int openInterpreter(FILE * in, FILE * out, recordid hash) { char * line = NULL; size_t len = 0; int AUTOCOMMIT = 1; int debug = 0; int xid = -1; size_t read; fprintf(out, "> "); int ret = 0; if(!AUTOCOMMIT) { xid = Tbegin(); } while((read = getline(&line, &len, in)) != -1) { if(line[0] == '!') { if(!strncmp(line+1,"debug",strlen("debug"))) { debug = !debug; if(debug) fprintf(out, "Enabling debugging\n"); else fprintf(out, "Disabling debugging\n"); } else if(!strncmp(line+1,"regions",strlen("regions"))) { fprintf(out, "Boundary tag pages:\n"); pageid_t pid = REGION_FIRST_TAG; boundary_tag tag; TregionReadBoundaryTag(-1,pid,&tag); int done = 0; while(!done) { fprintf(out, "\tpageid=%lld\ttype=%d\tsize=%lld\n", pid, tag.allocation_manager, tag.size); if(tag.size == UINT32_MAX) { fprintf(out, "\t[EOF]\n"); } int err = TregionNextBoundaryTag(-1,&pid,&tag,0); if(!err) { done = 1; } } } else if(!strncmp(line+1,"autocommit",strlen("autocommit"))) { if(AUTOCOMMIT) { // we're not in a transaction fprintf(out, "Disabling autocommit\n"); AUTOCOMMIT = 0; xid = Tbegin(); } else { fprintf(out, "Enabling autocommit\n"); AUTOCOMMIT = 1; Tcommit(xid); } /* } else if(!strncmp(line+1,"parseTuple",strlen("parseToken"))) { char * c = line + 1 + strlen("parseToken"); char ** toks = parseTuple(&c); for(int i = 0; toks[i]; i++) { fprintf(out, "col %d = ->%s<-\n", i, toks[i]); } fprintf(out, "trailing stuff: %s", c); } else if(!strncmp(line+1,"parseExpression", strlen("parseExpression"))) { char * c = line + 1 + strlen("parseExpression"); lladdIterator_t * it = parseExpression(xid, hash, &c); it = 0; */ } else if(!strncmp(line+1,"exit",strlen("exit"))) { break; } else if(!strncmp(line+1,"shutdown",strlen("shutdown"))) { ret = SHUTDOWN_SERVER; break; } } else { expr_list * results = 0; parse(line, &results); for(int i = 0; results && i < results->count; i++) { expr * e = results->ents[i]; switch(e->typ) { case query_typ: { lladdIterator_t * it = ReferentialAlgebra_ExecuteQuery(xid, context, e->u.q); if(it) { while(Titerator_next(xid,it)) { byte * tup; Titerator_value(xid,it, &tup); char * tupleString = stringTuple(*(tuple_t*)tup); fprintf(out, "%s\n", tupleString); free(tupleString); } Titerator_close(xid,it); } } break; case insert_typ: { if(AUTOCOMMIT) { xid = Tbegin(); } ReferentialDML_ExecuteInsert(xid, context, e->u.i); if(AUTOCOMMIT) { Tcommit(xid); xid = -1;} } break; case delete_typ: { if(AUTOCOMMIT) { xid = Tbegin(); } ReferentialDML_ExecuteDelete(xid, context, e->u.d); if(AUTOCOMMIT) { Tcommit(xid); xid = -1;} } break; case create_typ: { if(AUTOCOMMIT) { xid = Tbegin(); } ReferentialDDL_CreateTable(xid, context, e->u.c); if(AUTOCOMMIT) { xid = Tcommit(xid); xid = -1;} } break; default: abort(); } } //XXX typecheck(context, results); if(results) { char * str = pp_expr_list(results); printf("%s", str); free(str); } else { printf("No results\n"); } } fprintf(out, "> "); } if(!AUTOCOMMIT) { Tcommit(xid); } free(line); fprintf(out, "\n"); return ret; }