value arc_hash_insert(arc *c, value hash, value key, value val) { unsigned int hv, index, i; value e; index = 0; /* First of all, look for the key if a binding already exists for it */ e = hash_lookup(c, hash, key, &index); if (BOUND_P(e)) { /* if we are already bound, overwrite the old value */ e = VINDEX(HASH_TABLE(hash), index); BVALUE(e) = val; return(val); } /* Not yet bound. Look for a slot where we can put it */ if (HASH_NENTRIES(hash)+1 > HASH_LLIMIT(hash)) hashtable_expand(c, hash); SET_NENTRIES(hash, HASH_NENTRIES(hash)+1); hv = arc_hash(c, key); index = hv & TABLEMASK(hash); for (i=0;; i++) { e = VINDEX(HASH_TABLE(hash), index); /* If we see an empty bucket in our search, or if we see a bucket whose key is the same as the key specified, we have found the place where the element should go. This second case should never happen, based on what we did above, but hey, belt and suspenders. */ if (EMPTYP(e) || arc_is2(c, BKEY(e), key) == CTRUE) break; /* We found a bucket, but it is occupied by some other key. Continue probing. */ index = (index + PROBE(i)) & TABLEMASK(hash); } if (EMPTYP(e)) { /* No such key in the hash table yet. Create a bucket and assign it to the table. */ e = mkhashbucket(c, key, val, index, hash, INT2FIX(hv)); SVINDEX(HASH_TABLE(hash), index, e); } else { /* The key already exists. Use the current bucket but change the value to the value specified. */ BVALUE(e) = val; } return(val); }
static value hash_lookup(arc *c, value hash, value key, unsigned int *index) { unsigned int hv, i; value e; hv = arc_hash(c, key); *index = hv & TABLEMASK(hash); for (i=0;; i++) { *index = (*index + PROBE(i)) & TABLEMASK(hash); e = HASH_INDEX(hash, *index); /* CUNBOUND means there was never any element at that index, so we can stop. */ if (e == CUNBOUND) return(CUNBOUND); /* CUNDEF means that there was an element at that index, but it was deleted at some point, so we may need to continue probing. */ if (e == CUNDEF) continue; if (arc_is2(c, BKEY(e), key) == CTRUE) return(BVALUE(e)); } return(CUNBOUND); }
std::string MysqlProxy::routeSql(const char * sql_char,uint64_t routeid,const char *table) { std::string sql(sql_char); int tablenum = 1; int tableidx = 0; if(tablesplit.find(table) != tablesplit.end()) { tablenum = tablesplit[table]; tableidx = TABLEMASK(routeid) % tablenum; } std::string::size_type pos = sql.find(" from "); if(pos != std::string::npos) { pos = sql.find(table, pos); } //not find in from if( pos==std::string::npos){ // only change first pos = sql.find(table, 0); } //find table name if(pos != std::string::npos) { char tablename[256]= {0}; snprintf(tablename,sizeof(tablename),"_%u",tableidx); sql.insert(pos+strlen(table), tablename); } int dbidx = DBMASK(routeid)%dbnum; ServerContext & sc = servers[dbidx]; TRACE("routeid:"<<routeid<<",table:"<<table<<",host:"<<sc.host<<",port:"<<sc.port<<",sql:"<<sql); return sql; }