// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef sw_LRUCache_hpp
#define sw_LRUCache_hpp

#include "System/Debug.hpp"

#include <cstddef>
#include <functional>
#include <unordered_set>
#include <vector>

namespace sw {

// LRUCache is a least recently used cache of a fixed capacity.
template<typename KEY, typename DATA, typename HASH = std::hash<KEY> >
class LRUCache
{
	struct Entry;

public:
	using Key = KEY;
	using Data = DATA;
	using Hash = HASH;

	// view is a const accessor of a single cache entry.
	class view
	{
	public:
		inline view(Entry *);

		inline const Key &key() const;
		inline const Data &data() const;

	private:
		Entry *entry;
	};

	class iterator
	{
	public:
		inline iterator(Entry *);
		inline view operator*() const;
		inline iterator &operator++();
		inline bool operator==(const iterator &) const;
		inline bool operator!=(const iterator &) const;

	private:
		Entry *entry;
	};

	// Construct a LRU cache with the given maximum number of entries.
	inline LRUCache(size_t capacity);
	inline ~LRUCache() = default;

	// lookup() looks up the cache entry with the given key.
	// If the entry is found, this is moved to the most-recent position in the
	// cache, and its data is returned.
	// If the entry is not found, then a default initialized Data is returned.
	inline Data lookup(const Key &key);

	// add() adds the data to the cache using the given key, placed at the
	// most-recent position in the cache.
	// If an existing entry exists in the cache with the given key, then this is
	// replaced with data.
	// If no existing entry exists in the cache, and the cache is already full
	// then the least recently used entry is evicted before adding the new
	// entry.
	inline void add(const Key &key, const Data &data);

	// clear() clears the cache of all elements.
	inline void clear();

	// Range based iterators.
	inline iterator begin() const;
	inline iterator end() const;

private:
	LRUCache(const LRUCache &) = delete;
	LRUCache(LRUCache &&) = delete;
	LRUCache &operator=(const LRUCache &) = delete;
	LRUCache &operator=(LRUCache &&) = delete;

	//Keyed holds a key. See find() for more information.
	struct Keyed
	{
		Key key = {};
	};

	// Cache entry structure.
	// Holds the unique copy of the key and data, along with pointers for
	// maintaining the linked list.
	struct Entry : Keyed
	{
		Data data = {};
		Entry *next = nullptr;
		Entry *prev = nullptr;
	};

	// KeyedComparator is a custom hasher and equality helper for Keyed.
	struct KeyedComparator
	{
		// Hash function.
		inline uint64_t operator()(const Keyed *k) const;

		// Equality function.
		inline uint64_t operator()(const Keyed *a, const Keyed *b) const;
	};

	// find() returns the Entry* for the given key, or nullptr.
	// find() performs this by casting the Key pointer to a Keyed pointer for
	// searching the std::unordered_set.
	//
	// This is to avoid having a duplicate Key held by both an
	// unordered_map<Key, Entry*> and the Entry itself, as the Key type may be
	// large.
	//
	// While we could use an unordered_set<Entry*>, this then requires the
	// construction of a temporary Entry to perform the call to
	// unordered_set<Entry*>::find(). This is undesirable as the Data type might
	// be large or have an expensive constructor.
	//
	// C++20 gains a new templated overload for unordered_set<Entry*>::find()
	// which would allow us to use unordered_set<Entry*>::find(Key*).
	// Until we can use C++20, keep this casting nastiness hidden away in this
	// one function.
	inline Entry *find(const Key &key);

	// unlinks the entry from the list it is linked in.
	inline void unlink(Entry *);

	// links the entry to the head of the LRU.
	inline void link(Entry *);

	// storage holds the allocations of all the entries.
	// This vector must not change size for the lifetime of the cache.
	std::vector<Entry> storage;

	// set is an unordered set of Keyed*, using the KeyedComparator for hash and
	// equality testing.
	std::unordered_set<const Keyed *, KeyedComparator, KeyedComparator> set;

	Entry *free = nullptr;  // Singly-linked (prev is nullptr) list of free entries.
	Entry *head = nullptr;  // Pointer to the most recently used entry in the LRU.
	Entry *tail = nullptr;  // Pointer to the least recently used entry in the LRU.
};

////////////////////////////////////////////////////////////////////////////////
// LRUCache<>::view
////////////////////////////////////////////////////////////////////////////////
template<typename KEY, typename DATA, typename HASH>
LRUCache<KEY, DATA, HASH>::view::view(Entry *entry)
    : entry(entry)
{}

template<typename KEY, typename DATA, typename HASH>
const KEY &LRUCache<KEY, DATA, HASH>::view::key() const
{
	return entry->key;
}

template<typename KEY, typename DATA, typename HASH>
const DATA &LRUCache<KEY, DATA, HASH>::view::data() const
{
	return entry->data;
}

////////////////////////////////////////////////////////////////////////////////
// LRUCache<>::iterator
////////////////////////////////////////////////////////////////////////////////
template<typename KEY, typename DATA, typename HASH>
LRUCache<KEY, DATA, HASH>::iterator::iterator(Entry *entry)
    : entry(entry)
{}

template<typename KEY, typename DATA, typename HASH>
typename LRUCache<KEY, DATA, HASH>::view LRUCache<KEY, DATA, HASH>::iterator::operator*() const
{
	return view{ entry };
}

template<typename KEY, typename DATA, typename HASH>
typename LRUCache<KEY, DATA, HASH>::iterator &LRUCache<KEY, DATA, HASH>::iterator::operator++()
{
	entry = entry->next;
	return *this;
}

template<typename KEY, typename DATA, typename HASH>
bool LRUCache<KEY, DATA, HASH>::iterator::operator==(const iterator &rhs) const
{
	return entry == rhs.entry;
}

template<typename KEY, typename DATA, typename HASH>
bool LRUCache<KEY, DATA, HASH>::iterator::operator!=(const iterator &rhs) const
{
	return entry != rhs.entry;
}

////////////////////////////////////////////////////////////////////////////////
// LRUCache<>
////////////////////////////////////////////////////////////////////////////////
template<typename KEY, typename DATA, typename HASH>
LRUCache<KEY, DATA, HASH>::LRUCache(size_t capacity)
    : storage(capacity)
{
	for(size_t i = 0; i < capacity; i++)
	{
		Entry *entry = &storage[i];
		entry->next = free;  // No need for back link here.
		free = entry;
	}
}

template<typename KEY, typename DATA, typename HASH>
DATA LRUCache<KEY, DATA, HASH>::lookup(const Key &key)
{
	if(Entry *entry = find(key))
	{
		unlink(entry);
		link(entry);
		return entry->data;
	}
	return {};
}

template<typename KEY, typename DATA, typename HASH>
void LRUCache<KEY, DATA, HASH>::add(const Key &key, const Data &data)
{
	if(Entry *entry = find(key))
	{
		// Move entry to front.
		unlink(entry);
		link(entry);
		entry->data = data;
		return;
	}

	Entry *entry = free;
	if(entry)
	{
		// Unlink from free.
		free = entry->next;
		entry->next = nullptr;
	}
	else
	{
		// Unlink least recently used.
		entry = tail;
		unlink(entry);
		set.erase(entry);
	}

	// link as most recently used.
	link(entry);
	if(tail == nullptr)
	{
		tail = entry;
	}

	entry->key = key;
	entry->data = data;
	set.emplace(entry);
}

template<typename KEY, typename DATA, typename HASH>
void LRUCache<KEY, DATA, HASH>::clear()
{
	while(Entry *entry = head)
	{
		unlink(entry);
		entry->next = free;  // No need for back link here.
		free = entry;
	}
	set.clear();
}

template<typename KEY, typename DATA, typename HASH>
typename LRUCache<KEY, DATA, HASH>::iterator LRUCache<KEY, DATA, HASH>::begin() const
{
	return { head };
}

template<typename KEY, typename DATA, typename HASH>
typename LRUCache<KEY, DATA, HASH>::iterator LRUCache<KEY, DATA, HASH>::end() const
{
	return { nullptr };
}

template<typename KEY, typename DATA, typename HASH>
void LRUCache<KEY, DATA, HASH>::unlink(Entry *entry)
{
	if(head == entry) { head = entry->next; }
	if(tail == entry) { tail = entry->prev; }
	if(entry->prev) { entry->prev->next = entry->next; }
	if(entry->next) { entry->next->prev = entry->prev; }
	entry->prev = nullptr;
	entry->next = nullptr;
}

template<typename KEY, typename DATA, typename HASH>
void LRUCache<KEY, DATA, HASH>::link(Entry *entry)
{
	ASSERT_MSG(entry->next == nullptr, "link() called on entry already linked");
	ASSERT_MSG(entry->prev == nullptr, "link() called on entry already linked");
	if(head)
	{
		entry->next = head;
		head->prev = entry;
	}
	head = entry;
	if(!tail) { tail = entry; }
}

template<typename KEY, typename DATA, typename HASH>
typename LRUCache<KEY, DATA, HASH>::Entry *LRUCache<KEY, DATA, HASH>::find(const Key &key)
{
	auto asKeyed = reinterpret_cast<const Keyed *>(&key);
	auto it = set.find(asKeyed);
	if(it == set.end())
	{
		return nullptr;
	}
	return const_cast<Entry *>(static_cast<const Entry *>(*it));
}

////////////////////////////////////////////////////////////////////////////////
// LRUCache<>::KeyedComparator
////////////////////////////////////////////////////////////////////////////////
template<typename KEY, typename DATA, typename HASH>
uint64_t LRUCache<KEY, DATA, HASH>::KeyedComparator::operator()(const Keyed *k) const
{
	return Hash()(k->key);
}

template<typename KEY, typename DATA, typename HASH>
uint64_t LRUCache<KEY, DATA, HASH>::KeyedComparator::operator()(const Keyed *a, const Keyed *b) const
{
	return a->key == b->key;
}

}  // namespace sw

#endif  // sw_LRUCache_hpp
