<pre name="code" class="cpp">/*
* common.h
*
* Created on: 2015年8月17日
* Author: qiangqaz
*/
#ifndef COMMON_H_
#define COMMON_H_
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef signed char s8;
typedef short s16;
typedef int s32;
typedef long long s64;
#define min(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; })
#define max(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x > _y ? _x : _y; })
/*
* swap - swap value of @a and @b
*/
#define swap(a, b) \
do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
#define USHORT_MAX ((u16)(~0U))
#define SHORT_MAX ((s16)(USHORT_MAX>>1))
#define SHORT_MIN (-SHORT_MAX - 1)
#define INT_MAX ((int)(~0U>>1))
#define INT_MIN (-INT_MAX - 1)
#define UINT_MAX (~0U)
#define LONG_MAX ((long)(~0UL>>1))
#define LONG_MIN (-LONG_MAX - 1)
#define ULONG_MAX (~0UL)
#define LLONG_MAX ((long long)(~0ULL>>1))
#define LLONG_MIN (-LLONG_MAX - 1)
#define ULLONG_MAX (~0ULL)
#ifndef offset_of
#define offset_of(type, memb) \
((unsigned long)(&((type *)0)->memb))
#endif
#ifndef container_of
#define container_of(obj, type, memb) \
((type *)(((char *)obj) - offset_of(type, memb)))
#endif
/* print function stack address: __builtin_return_address(0) */
#endif /* COMMON_H_ */
/*
* LRU.h
*
* Created on: 2016年2月26日
* Author: qiangqaz
*/
#ifndef LRU_H_
#define LRU_H_
typedef struct S_LRU_LIST
{
u32 data;
struct list_head d_list;
}LRU_LIST;
typedef struct S_LRU
{
u32 max_len;
u32 cur_len;
int (*func)(int, int);
struct list_head lru_head;
}LRU;
LRU* LRU_init(u32 length);
void LRU_destroy(LRU **lru);
int LRU_insert(LRU *lru, u32 key);
int LRU_get(LRU *lru, u32 key);
#endif /* LRU_H_ */
/*
* list.h
*
* Created on: 2015年8月17日
* Author: qiangqaz
*/
#ifndef LIST_H_
#define LIST_H_
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
static inline void __list_add(struct list_head *_new, struct list_head *prev, struct list_head *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
/**
* list_add - add a _new entry
* @_new: _new entry to be added
* @head: list head to add it after
*
* Insert a _new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head, head->next);
}
/**
* list_add_tail - add a _new entry
* @_new: _new entry to be added
* @head: list head to add it before
*
* Insert a _new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = 0;
entry->prev = 0;
}
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
/*
* LRU.c
*
* Created on: 2016年2月26日
* Author: qiangqaz
*/
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "list.h"
#include "LRU.h"
int LRU_Compare(int data, int key)
{
if (key == data)
return 0;
else
return 1;
}
LRU* LRU_init(u32 length)
{
LRU *lru = NULL;
lru = (LRU* )malloc(sizeof(LRU));
if (NULL == lru)
{
return NULL;
}
lru->max_len = length;
lru->cur_len = 0;
lru->func = &LRU_Compare;
INIT_LIST_HEAD(&(lru->lru_head));
return lru;
}
void LRU_destroy(LRU **lru_del)
{
LRU_LIST *lru_list = NULL;
struct list_head *pos;
LRU *lru = *lru_del;
if (lru == NULL)
{
return;
}
while (!list_empty(&lru->lru_head))
{
pos = lru->lru_head.next;
list_del(pos);
lru_list = container_of(pos, LRU_LIST, d_list);
free(lru_list);
}
/*
for (pos = lru->lru_head.next; pos != &(lru->lru_head);pos = lru->lru_head.next)
{
lru_list = container_of(pos, LRU_LIST, d_list);
list_del(pos);
free(lru_list);
}
*/
free(lru);
lru = NULL;
}
int LRU_insert(LRU *lru, u32 key)
{
LRU_LIST *lru_list = NULL;
struct list_head *pos = NULL;
if (lru == NULL)
return -1;
if (lru->cur_len >= lru->max_len)
{
pos = lru->lru_head.prev;
list_move(pos, &(lru->lru_head));
lru_list = container_of(pos, LRU_LIST, d_list);
lru_list->data = key;
return 0;
}
lru_list = malloc(sizeof(LRU_LIST));
lru_list->data = key;
list_add(&(lru_list->d_list), &(lru->lru_head));
lru->cur_len++;
return 0;
}
int LRU_get(LRU *lru, u32 key)
{
LRU_LIST *lru_list = NULL;
struct list_head *pos;
if (lru == NULL)
return -1;
__list_for_each(pos, &(lru->lru_head))
{
lru_list = container_of(pos, LRU_LIST, d_list);
if (0 == lru->func(lru_list->data, key))
{
list_move(pos, &(lru->lru_head));
}
}
return -1;
}
<pre name="code" class="cpp">/*
============================================================================
Name : main.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "list.h"
#include "LRU.h"
void lru_print(LRU *lru)
{
LRU_LIST *lru_list = NULL;
struct list_head *pos;
__list_for_each(pos, &(lru->lru_head))
{
lru_list = container_of(pos, LRU_LIST, d_list);
printf("%d\n",lru_list->data);
}
}
int main(void)
{
LRU *lru = NULL;
lru = LRU_init(10);
LRU_insert(lru, 10);
LRU_insert(lru, 13);
LRU_insert(lru, 8);
LRU_insert(lru, 45);
LRU_insert(lru, 4545);
LRU_insert(lru, 123);
LRU_insert(lru, 64);
LRU_insert(lru, 55);
LRU_insert(lru, 23);
LRU_insert(lru, 53);
LRU_insert(lru, 78);
LRU_insert(lru, 96);
lru_print(lru);
printf("begin to get key=4545\n");
(void)LRU_get(lru, 4545);
lru_print(lru);
printf("begin to get key=123\n");
(void)LRU_get(lru, 123);
lru_print(lru);
LRU_destroy(&lru);
return EXIT_SUCCESS;
}