-
Notifications
You must be signed in to change notification settings - Fork 8
/
cs.c
107 lines (88 loc) · 2.39 KB
/
cs.c
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
* Copyright (C) 2016 Wentao Shang
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup net_ndn
* @{
*
* @file
*
* @author Wentao Shang <[email protected]>
*/
#include "cs.h"
#include "encoding/interest.h"
#include "encoding/data.h"
#include <utlist.h>
#include <debug.h>
#include <assert.h>
#include <stdlib.h>
static ndn_cs_entry_t *_cs;
static int _cs_size;
#define MAX_CS_SIZE 24000
static void _ndn_cs_remove(ndn_cs_entry_t* entry)
{
DL_DELETE(_cs, entry);
_cs_size -= entry->data->block.len;
DEBUG("ndn: remove cs entry (_cs_size=%d)\n", _cs_size);
ndn_shared_block_release(entry->data);
free(entry);
}
int ndn_cs_add(ndn_shared_block_t* data)
{
assert(data != NULL);
if (_cs_size + data->block.len > MAX_CS_SIZE) {
if (data->block.len > (MAX_CS_SIZE >> 1)) {
DEBUG("ndn: data packet too big\n");
return -1;
}
assert(_cs != NULL);
// clean up cs by half
while (_cs_size + data->block.len > (MAX_CS_SIZE >> 1)) {
// remove front entries (FIFO)
_ndn_cs_remove(_cs);
}
}
// allocate new entry
ndn_cs_entry_t *entry = (ndn_cs_entry_t*)malloc(sizeof(ndn_cs_entry_t));
if (entry == NULL) {
DEBUG("ndn: cannot allocate pit entry\n");
return -1;
}
entry->data = ndn_shared_block_copy(data);
entry->prev = entry->next = NULL;
DL_PREPEND(_cs, entry);
_cs_size += entry->data->block.len;
DEBUG("ndn: add new cs entry (_cs_size=%d)\n", _cs_size);
return 0;
}
ndn_shared_block_t* ndn_cs_match(ndn_block_t* interest)
{
ndn_block_t iname;
int r = ndn_interest_get_name(interest, &iname);
if (r != 0) {
DEBUG("ndn: cannot get name from interest for cs matching\n");
return NULL;
}
ndn_cs_entry_t *entry;
DL_FOREACH(_cs, entry) {
ndn_block_t dname;
r = ndn_data_get_name(&entry->data->block, &dname);
assert(r == 0);
r = ndn_name_compare_block(&iname, &dname);
if (r == -2 || r == 0) {
// either iname is a prefix of dname, or they are the same
return ndn_shared_block_copy(entry->data);
}
}
return NULL;
}
void ndn_cs_init(void)
{
_cs = NULL;
_cs_size = 0;
}
/** @} */