A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 121 lines 3.8 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * 9 * Copyright (C) 2003 Tat Tang 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 2 14 * of the License, or (at your option) any later version. 15 * 16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 17 * KIND, either express or implied. 18 * 19 ****************************************************************************/ 20 21#include "lru.h" 22 23struct lru_node 24{ 25 short _next; 26 short _prev; 27 unsigned char data[1]; /* place holder */ 28}; 29 30#define lru_node_p(pl, x) \ 31 ((struct lru_node*)(pl->_base + pl->_slot_size * x)) 32 33/******************************************************************************* 34 * lru_create 35 ******************************************************************************/ 36void lru_create(struct lru* pl, void *buf, short size, short data_size) 37{ 38 pl->_base = (unsigned char*) buf; 39 pl->_slot_size = data_size + LRU_SLOT_OVERHEAD; 40 41 pl->_size = size; 42 43 pl->_head = 0; 44 pl->_tail = pl->_size - 1; 45 46 /* Initialise slots */ 47 int i; 48 for (i=0; i<pl->_size; i++) 49 { 50 lru_node_p(pl, i)->_next = i + 1; 51 lru_node_p(pl, i)->_prev = i - 1; 52 } 53 54 /* Fix up head and tail to form circular buffer */ 55 lru_node_p(pl, 0)->_prev = pl->_tail; 56 lru_node_p(pl, pl->_tail)->_next = pl->_head; 57} 58 59/******************************************************************************* 60 * lru_traverse 61 ******************************************************************************/ 62void lru_traverse(struct lru* pl, void (*callback)(void* data)) 63{ 64 short i; 65 struct lru_node* slot; 66 short loc = pl->_head; 67 68 for (i = 0; i < pl->_size; i++) 69 { 70 slot = lru_node_p(pl, loc); 71 callback(slot->data); 72 loc = slot->_next; 73 } 74} 75 76/******************************************************************************* 77 * lru_touch 78 ******************************************************************************/ 79void lru_touch(struct lru* pl, short handle) 80{ 81 if (handle == pl->_head) 82 { 83 pl->_head = lru_node_p(pl, pl->_head)->_next; 84 pl->_tail = lru_node_p(pl, pl->_tail)->_next; 85 return; 86 } 87 88 if (handle == pl->_tail) 89 { 90 return; 91 } 92 93 /* Remove current node from linked list */ 94 struct lru_node* curr_node = lru_node_p(pl, handle); 95 struct lru_node* prev_node = lru_node_p(pl, curr_node->_prev); 96 struct lru_node* next_node = lru_node_p(pl, curr_node->_next); 97 98 prev_node->_next = curr_node->_next; 99 next_node->_prev = curr_node->_prev; 100 101 /* insert current node at tail */ 102 struct lru_node* tail_node = lru_node_p(pl, pl->_tail); 103 short tail_node_next_handle = tail_node->_next; /* Bug fix */ 104 struct lru_node* tail_node_next = lru_node_p(pl, tail_node_next_handle); /* Bug fix */ 105 106 curr_node->_next = tail_node->_next; 107 curr_node->_prev = pl->_tail; 108 tail_node_next->_prev = handle; /* Bug fix */ 109 tail_node->_next = handle; 110 111 pl->_tail = handle; 112} 113 114/******************************************************************************* 115 * lru_data 116 ******************************************************************************/ 117void *lru_data(struct lru* pl, short handle) 118{ 119 return lru_node_p(pl, handle)->data; 120} 121