-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathcache.c
More file actions
85 lines (69 loc) · 2 KB
/
Copy pathcache.c
File metadata and controls
85 lines (69 loc) · 2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
* Copyright (c) 2014, Zhiyong Liu <Neesenk at gmail dot com>
* All rights reserved.
*/
#include <assert.h>
#include <stdlib.h>
struct circlecache
{
size_t max;
size_t size;
size_t read_cursor; // 缓存的首地址偏移
size_t writer_cursor; // 缓存的尾地址偏移
char buffer[];
};
struct item
{
unsigned size;
char contents[];
};
static inline unsigned int min_power_of_2(unsigned int in)
{
unsigned int v = in, r = 1;
while (v >>= 1)
r <<= 1;
return (r != in) ? (r << 1) : r;
}
struct circlecache *circlecache_create(size_t size, size_t max)
{
struct circlecache *ret = NULL;
size = min_power_of_2(size);
if ((ret = calloc(1, sizeof(*ret) + max + size + sizeof(struct item))) == NULL)
return NULL;
ret->size = size;
ret->max = max;
return ret;
}
void circlecache_destroy(struct circlecache *cache)
{
if (cache)
free(cache);
}
void *circlecache_alloc(struct circlecache *cache, size_t size)
{
struct item *item = NULL;
size_t left = (cache->read_cursor + size - cache->writer_cursor - 1) & (~cache->size);
if (size > cache->max)
return NULL;
if (size + cache->max + sizeof(struct item) > left)
return NULL;
item = (struct item *)(cache->buffer + cache->writer_cursor);
cache->writer_cursor = (cache->writer_cursor + size + sizeof(struct item)) & (~cache->size); //移动尾部指针
item->size = size;
return item->contents;
}
void *circlecache_read(struct circlecache *cache, size_t *size)
{
struct item *item = (struct item *)(cache->buffer + cache->read_cursor);
if (cache->read_cursor == cache->writer_cursor)
return 0;
assert(item->size <= cache->max);
cache->read_cursor = (cache->read_cursor + item->size + sizeof(struct item)) & (~cache->size); // 移动头部指针
*size = item->size;
return item->contents;
}
void circlecache_clear(struct circlecache *cache)
{
cache->read_cursor = 0;
cache->writer_cursor = 0;
}