ZBLOG

redis太大了,请使用C语言给出一个性能好、稳定性高,稍微简单一点的缓存代码。需求是存储变长的数据,支持多线程,即需要支持多线程安全耽误进行读写操作

当然可以!下面是一个使用 C 语言实现的简单线程安全的缓存库示例。这个实现利用了互斥锁来确保多线程环境下的安全性,支持变长数据存储。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <pthread.h>
  5. #define CACHE_SIZE 1024
  6. typedef struct CacheItem {
  7. char *key;
  8. char *value;
  9. size_t value_len;
  10. struct CacheItem *next;
  11. } CacheItem;
  12. typedef struct {
  13. CacheItem **items;
  14. size_t size;
  15. pthread_mutex_t lock;
  16. } Cache;
  17. Cache* create_cache(size_t size) {
  18. Cache *cache = (Cache *)malloc(sizeof(Cache));
  19. cache->size = size;
  20. cache->items = (CacheItem **)calloc(size, sizeof(CacheItem *));
  21. pthread_mutex_init(&cache->lock, NULL);
  22. return cache;
  23. }
  24. unsigned long hash(const char *key) {
  25. unsigned long hash = 5381;
  26. int c;
  27. while ((c = *key++)) {
  28. hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
  29. }
  30. return hash;
  31. }
  32. void cache_set(Cache *cache, const char *key, const char *value, size_t value_len) {
  33. unsigned long index = hash(key) % cache->size;
  34. pthread_mutex_lock(&cache->lock);
  35. // Create a new item
  36. CacheItem *new_item = (CacheItem *)malloc(sizeof(CacheItem));
  37. new_item->key = strdup(key);
  38. new_item->value_len = value_len;
  39. // Allocate memory for the variable-length data
  40. new_item->value = (char *)malloc(value_len);
  41. memcpy(new_item->value, value, value_len);
  42. // Insert it into the linked list at this index
  43. new_item->next = cache->items[index];
  44. cache->items[index] = new_item;
  45. pthread_mutex_unlock(&cache->lock);
  46. }
  47. char* cache_get(Cache *cache, const char *key, size_t *out_value_len) {
  48. unsigned long index = hash(key) % cache->size;
  49. pthread_mutex_lock(&cache->lock);
  50. CacheItem *item = cache->items[index];
  51. while (item != NULL) {
  52. if (strcmp(item->key, key) == 0) {
  53. pthread_mutex_unlock(&cache->lock);
  54. if(out_value_len)
  55. *out_value_len=item->value_len; // Return the length of the value
  56. return item->value; // Return the found value
  57. }
  58. item = item->next;
  59. }
  60. pthread_mutex_unlock(&cache->lock);
  61. return NULL; // Not found
  62. }
  63. // Free allocated memory in the cache and its items.
  64. void free_cache(Cache* cache){
  65. for(size_t i=0;i<cache->size;i++){
  66. CacheItem* item=cache->items[i];
  67. while(item!=NULL){
  68. CacheItem* tmp=item;
  69. item=item->next;
  70. free(tmp -> key); // free the key string
  71. free(tmp -> value); // free the variable-length data
  72. free(tmp);
  73. }
  74. }
  75. free(cache -> items);
  76. pthread_mutex_destroy(&cache -> lock);
  77. free(cache);
  78. }
  79. int main() {
  80. Cache* my_cache=create_cache(CACHE_SIZE);
  81. const char* key="test_key";
  82. const char* value="Hello World!";
  83. printf("Setting key: %s with value: %s\n", key,value);
  84. cache_set(my_cache,key,value,strlen(value)+1);
  85. size_t len=0;
  86. char* result=cache_get(my_cache,key,&len);
  87. if(result){
  88. printf("Retrieved from cache: %s\n",result);
  89. printf("Length of retrieved data is: %zu\n", len-1 );// Subtracting one to exclude null terminator
  90. }else{
  91. printf("Key not found.\n");
  92. }
  93. free_cache(my_cache);
  94. return 0;
  95. }

功能说明:

  • create_cache: 创建一个缓存,初始化大小和互斥锁。
  • hash: 简单的哈希函数,用于计算键值对在数组中的索引。
  • cache_set: 设置缓存项,并保证多线程安全。
  • cache_get: 从缓存中获取项,同样保证多线程安全。
  • free_cache: 清理内存,以防止内存泄漏。

注意事项:

  1. 使用时请确保适当管理内存,避免内存泄漏。
  2. 实际应用中可能需要更复杂的错误处理逻辑。
  3. 根据需要可扩展功能,例如添加过期时间等特性。

这是一个简单的示例,如果需要更复杂或特定功能,可以根据需求进行进一步扩展。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=20308

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?