Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/fs/btrfs/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 3 kB image not shown  

Quelle  lru_cache.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0

#include <linux/mm.h>
#include "lru_cache.h"
#include "messages.h"

/*
 * Initialize a cache object.
 *
 * @cache:      The cache.
 * @max_size:   Maximum size (number of entries) for the cache.
 *              Use 0 for unlimited size, it's the user's responsibility to
 *              trim the cache in that case.
 */

void btrfs_lru_cache_init(struct btrfs_lru_cache *cache, unsigned int max_size)
{
 INIT_LIST_HEAD(&cache->lru_list);
 mt_init(&cache->entries);
 cache->size = 0;
 cache->max_size = max_size;
}

static struct btrfs_lru_cache_entry *match_entry(struct list_head *head, u64 key,
       u64 gen)
{
 struct btrfs_lru_cache_entry *entry;

 list_for_each_entry(entry, head, list) {
  if (entry->key == key && entry->gen == gen)
   return entry;
 }

 return NULL;
}

/*
 * Lookup for an entry in the cache.
 *
 * @cache:      The cache.
 * @key:        The key of the entry we are looking for.
 * @gen:        Generation associated to the key.
 *
 * Returns the entry associated with the key or NULL if none found.
 */

struct btrfs_lru_cache_entry *btrfs_lru_cache_lookup(struct btrfs_lru_cache *cache,
           u64 key, u64 gen)
{
 struct list_head *head;
 struct btrfs_lru_cache_entry *entry;

 head = mtree_load(&cache->entries, key);
 if (!head)
  return NULL;

 entry = match_entry(head, key, gen);
 if (entry)
  list_move_tail(&entry->lru_list, &cache->lru_list);

 return entry;
}

/*
 * Remove an entry from the cache.
 *
 * @cache:     The cache to remove from.
 * @entry:     The entry to remove from the cache.
 *
 * Note: this also frees the memory used by the entry.
 */

void btrfs_lru_cache_remove(struct btrfs_lru_cache *cache,
       struct btrfs_lru_cache_entry *entry)
{
 struct list_head *prev = entry->list.prev;

 ASSERT(cache->size > 0);
 ASSERT(!mtree_empty(&cache->entries));

 list_del(&entry->list);
 list_del(&entry->lru_list);

 if (list_empty(prev)) {
  struct list_head *head;

  /*
 * If previous element in the list entry->list is now empty, it
 * means it's a head entry not pointing to any cached entries,
 * so remove it from the maple tree and free it.
 */

  head = mtree_erase(&cache->entries, entry->key);
  ASSERT(head == prev);
  kfree(head);
 }

 kfree(entry);
 cache->size--;
}

/*
 * Store an entry in the cache.
 *
 * @cache:      The cache.
 * @entry:      The entry to store.
 *
 * Returns 0 on success and < 0 on error.
 */

int btrfs_lru_cache_store(struct btrfs_lru_cache *cache,
     struct btrfs_lru_cache_entry *new_entry,
     gfp_t gfp)
{
 const u64 key = new_entry->key;
 struct list_head *head;
 int ret;

 head = kmalloc(sizeof(*head), gfp);
 if (!head)
  return -ENOMEM;

 ret = mtree_insert(&cache->entries, key, head, gfp);
 if (ret == 0) {
  INIT_LIST_HEAD(head);
  list_add_tail(&new_entry->list, head);
 } else if (ret == -EEXIST) {
  kfree(head);
  head = mtree_load(&cache->entries, key);
  ASSERT(head != NULL);
  if (match_entry(head, key, new_entry->gen) != NULL)
   return -EEXIST;
  list_add_tail(&new_entry->list, head);
 } else if (ret < 0) {
  kfree(head);
  return ret;
 }

 if (cache->max_size > 0 && cache->size == cache->max_size) {
  struct btrfs_lru_cache_entry *lru_entry;

  lru_entry = list_first_entry(&cache->lru_list,
          struct btrfs_lru_cache_entry,
          lru_list);
  btrfs_lru_cache_remove(cache, lru_entry);
 }

 list_add_tail(&new_entry->lru_list, &cache->lru_list);
 cache->size++;

 return 0;
}

/*
 * Empty a cache.
 *
 * @cache:     The cache to empty.
 *
 * Removes all entries from the cache.
 */

void btrfs_lru_cache_clear(struct btrfs_lru_cache *cache)
{
 struct btrfs_lru_cache_entry *entry;
 struct btrfs_lru_cache_entry *tmp;

 list_for_each_entry_safe(entry, tmp, &cache->lru_list, lru_list)
  btrfs_lru_cache_remove(cache, entry);

 ASSERT(cache->size == 0);
 ASSERT(mtree_empty(&cache->entries));
}

Messung V0.5
C=99 H=90 G=94

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.