bool Server::cache_set(const string &key,const char *value,size_t valuelen) { if(m_memcached_conn.number_of_hosts == 0){ return false; } /* vector<char> vv; for(size_t i=0;i<valuelen;i++){ vv.push_back(value[i]); } */ pthread_mutex_lock(&m_cache_lock); string cachekey = cache_hash(key); memcached_return_t rc= memcached_set(&m_memcached_conn, cachekey.c_str(), cachekey.size(), value, valuelen, 86400, 0); pthread_mutex_unlock(&m_cache_lock); if(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED){ TB_INFO("cache set ok: key="<<cachekey); return true; }else{ TB_ERROR("cache set failed: error="<<memcached_strerror(NULL, rc)<<",key="<<cachekey<<", valuelen="<<valuelen); return false; } }
CACHE_DECLARE(char *)ap_cache_generate_name(apr_pool_t *p, int dirlevels, int dirlength, const char *name) { char hashfile[66]; cache_hash(name, hashfile, dirlevels, dirlength); return apr_pstrdup(p, hashfile); }
struct bucket_t *cache_t::find(cache_key_t key) { assert(key != 0); bucket_t *b = buckets(); mask_t m = mask(); mask_t begin = cache_hash(key, m); mask_t i = begin; do { if (b[i].key() == 0 || b[i].key() == key) { return &b[i]; } } while ((i = cache_next(i, m)) != begin); return nullptr; }
char * cache_path(char *path, size_t len, enum cache_type type, char *query, int start, char *country, int anonymous, char search_user[], struct subnamesFormat *collections, int num_colls) { char tmppath[PATH_MAX]; char modquery[PATH_MAX]; unsigned int hash; char *p; char *cache; switch (type) { case CACHE_PREQUERY: cache = "var/cache/prequery_v_" CACHE_STRUCT_VERSION; break; case CACHE_SEARCH: cache = "var/cache/search_v_" CACHE_STRUCT_VERSION; break; } /* XXX: Base 64 encode the query */ strcpy(modquery, query); for (p = modquery; *p; p++) { if (*p == '/') *p = '-'; else if (*p == ' ') *p = '#'; } hash = cache_hash(modquery, start, country); p = (char *)&hash; strncpy(path, bfile(cache), len); mkdir(path, 0755); snprintf(tmppath, sizeof(tmppath), "/%x%x", *p & 0xF, (*p >> 4) & 0xF); strncat(path, tmppath, len); mkdir(path, 0755); p++; snprintf(tmppath, sizeof(tmppath), "/%x%x", *p & 0xF, (*p >> 4) & 0xF); strncat(path, tmppath, len); mkdir(path, 0755); snprintf(tmppath, sizeof(tmppath), "/%s.%d.%s.%s.%i", modquery, start, country, anonymous ? "anonymous":search_user, cache_collhash(collections, num_colls)); strncat(path, tmppath, len); return path; }
/* MUST BE CALLED WITH THE LOCK HELD */ int cache_add(request_header * req, void * key, uid_t uid, void * reply, int32_t reply_len, int close_socket, time_t refresh_interval) { struct cache_entry * entry = malloc(sizeof(*entry)); uint32_t index; if(!entry) return -1; /* query information */ entry->type = req->type; entry->key = malloc(req->key_len); if(!entry->key) { free(entry); return -1; } memcpy(entry->key, key, req->key_len); entry->key_len = req->key_len; entry->key_hash = cache_hash(key, req->key_len, req->type); /* cached information */ entry->reply = reply; entry->reply_len = reply_len; entry->close_socket = close_socket; /* refresh information */ entry->expire_time = time(NULL) + refresh_interval; entry->refresh_interval = refresh_interval; entry->refreshes = 0; /* chaining information */ index = entry->key_hash % HASH_SIZE; entry->point = &hash_table[index]; entry->chain = hash_table[index]; if(entry->chain) entry->chain->point = &entry->chain; hash_table[index] = entry; if(debug) printf("Adding cache entry for [%s] hash 0x%08x at index %d\n", (char *) key, entry->key_hash, index); return 0; }
/* MUST BE CALLED WITH THE LOCK HELD */ int cache_search(request_header * req, void * key, uid_t uid, struct cache_entry ** entry) { uint32_t hash = cache_hash(key, req->key_len, req->type); struct cache_entry * scan = hash_table[hash % HASH_SIZE]; for(scan = hash_table[hash % HASH_SIZE]; scan; scan = scan->chain) if(scan->key_hash == hash && scan->key_len == req->key_len && scan->type == req->type && !memcmp(scan->key, key, req->key_len)) break; if(!scan) return -1; /* don't return expired data, just leave it for cleanup */ if(time(NULL) > scan->expire_time) { /* the newly added one will occur before this one in * the hash chain, so this won't be touched again */ if(debug) printf("Expired cache entry for [%s], refreshes %d\n", (char *) scan->key, scan->refreshes); scan->refreshes = 5; return -1; } *entry = scan; return 0; }
bool Server::cache_get(const string &key,string &value) { if(m_memcached_conn.number_of_hosts == 0){ return false; } pthread_mutex_lock(&m_cache_lock); size_t valuelen = 0; memcached_return_t rc; uint32_t flags= 0; string cachekey = cache_hash(key); char *val = memcached_get(&m_memcached_conn, cachekey.c_str(), cachekey.size(), &valuelen, &flags, &rc); pthread_mutex_unlock(&m_cache_lock); if(val != NULL){ value = string(val,valuelen); free(val); return true; }else{ TB_ERROR("cache get failed: error="<<memcached_strerror(NULL, rc)<<",key="<<cachekey); return false; } }