// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_STORAGE_BLOBFS_BLOB_CACHE_H_
#define SRC_STORAGE_BLOBFS_BLOB_CACHE_H_

#ifndef __Fuchsia__
#error Fuchsia-only Header
#endif

#include <fbl/condition_variable.h>
#include <fbl/function.h>
#include <fbl/intrusive_wavl_tree.h>
#include <fbl/mutex.h>
#include <fbl/ref_ptr.h>

#include "src/lib/digest/digest.h"
#include "src/lib/storage/vfs/cpp/vnode.h"
#include "src/storage/blobfs/cache_node.h"
#include "src/storage/blobfs/cache_policy.h"
#include "src/storage/blobfs/metrics.h"

namespace blobfs {

using digest::Digest;

// BlobCache contains a collection of weak pointers to vnodes.
//
// This cache also helps manage the lifecycle of these vnodes, controlling what is cached
// when there are no more external references.
//
// Internally, the BlobCache contains a "live set" and "closed set" of vnodes.
// The "live set" contains all Vnodes with a strong reference.
// The "closed set" contains references to Vnodes which are not used, but which exist
// on-disk. These Vnodes may be stored in a "low-memory" state until they are requested.
//
// This class is thread-safe.
class BlobCache {
 public:
  DISALLOW_COPY_ASSIGN_AND_MOVE(BlobCache);
  BlobCache();
  ~BlobCache();

  // Empties the cache, evicting all open nodes and deleting all closed nodes.
  void Reset();

  // Sets the internal cache policy dealing with blob eviction.
  //
  // Refer to the declaration of |CachePolicy| for more information.
  void SetCachePolicy(CachePolicy policy) { cache_policy_ = policy; }

  // Iterates over all non-evicted cached nodes with strong references, invoking |callback| on
  // each one.
  //
  // If a node is inserted into the "live set" via a concurrent call to |Add|, or evicted
  // with a concurrent call to |Evict|, it is undefined if that node will be returned.
  //
  // Returns the first error encountered, or ZX_OK once finished.
  // |callback| respects flow control status codes (i.e. ZX_ERR_STOP, ZX_ERR_NEXT).
  using NextNodeCallback = fbl::Function<zx_status_t(fbl::RefPtr<CacheNode>)>;
  zx_status_t ForAllOpenNodes(NextNodeCallback callback);

  // Searches for a blob by |digest|.
  //
  // If a readable blob with the same name exists, it is (optionally) placed in |out|.
  // If no such blob is found, ZX_ERR_NOT_FOUND is returned.
  // |out| may be null. The same error code will be returned as if it was a valid pointer.
  // If |out| is not null, then the returned-by-strong-reference Vnode will exist in the "live
  // set".
  zx_status_t Lookup(const Digest& digest, fbl::RefPtr<CacheNode>* out) __WARN_UNUSED_RESULT;

  // Adds a blob to the "live set" of the cache. If |vnode->ShouldCache()| is true, then
  // this node will remain discoverable using |Lookup()|, even if no strong references
  // remain.
  //
  // Returns ZX_ERR_ALREADY_EXISTS if this blob could not be added because a node with the same
  // key already exists in the cache.
  zx_status_t Add(const fbl::RefPtr<CacheNode>& vnode) __WARN_UNUSED_RESULT;

  // Deletes a blob from the cache.
  // When the last strong reference is removed, it is put into a low-memory state, but
  // not placed into the "closed set" of the cache.
  // Future calls to "Lookup" will not be able to observe this node.
  //
  // Returns ZX_OK if the node was evicted from the cache.
  // Returns ZX_ERR_NOT_FOUND if the node was not in the cache.
  zx_status_t Evict(const fbl::RefPtr<CacheNode>& vnode) __WARN_UNUSED_RESULT;

 private:
  // Resurrects a Vnode with no strong references, and relocate it from the "live set" to the
  // "closed set".
  //
  // Precondition: The blob must have no strong references.
  // This function is currently only safe to call from CacheNode::fbl_recycle.
  void Downgrade(CacheNode* vn);
  friend void CacheNode::fbl_recycle();

  // Identical to |Evict|, but utilizing a raw pointer.
  //
  // This function is only safe to call from:
  // - |Evict|, where the strong reference guarantees that the node will exist in the |open_hash_|
  // or not at all, or
  // - |fbl_recycle|, where the refcount of zero will prevent other nodes from concurrently
  // acquiring a reference. In this case, an argument is passed, identifying that other nodes
  // observing the |open_hash_| via lookup should be signalled if this node is removed.
  zx_status_t EvictUnsafe(CacheNode* vnode, bool from_recycle = false);

  // Returns a strong reference to a node, if it exists. May relocate the
  // node from the |closed_hash_| to the |open_hash_| if no strong references
  // actively exist. |out| must not be nullptr.
  //
  // Returns ZX_OK if the node is found and returned.
  // Returns ZX_ERR_NOT_FOUND if the node doesn't exist in the cache.
  zx_status_t LookupLocked(const digest::Digest& key, fbl::RefPtr<CacheNode>* out)
      __TA_REQUIRES(hash_lock_);

  // Upgrades a Vnode which exists in the |closed_hash_| into |open_hash_|,
  // and acquire the strong reference the Vnode which was leaked by
  // |Downgrade()|, if it exists.
  //
  // Precondition: The Vnode must not exist in |open_hash_|.
  fbl::RefPtr<CacheNode> UpgradeLocked(const digest::Digest& key) __TA_REQUIRES(hash_lock_);

  // Resets the cache by deleting all members |closed_hash_|.
  void ResetLocked() __TA_REQUIRES(hash_lock_);

  // We need to define this structure to allow the CacheNodes to be indexable by a key
  // which is larger than a primitive type: the keys are 'digest::kSha256Length'
  // bytes long.
  struct MerkleRootTraits {
    static const digest::Digest& GetKey(const CacheNode& obj) { return obj.digest(); }
    static bool LessThan(const digest::Digest& d1, const digest::Digest& d2) { return d1 < d2; }
    static bool EqualTo(const digest::Digest& d1, const digest::Digest& d2) { return d1 == d2; }
  };

  // CacheNodes exist in the WAVLTree as long as one or more reference exists;
  // when the Vnode is deleted, it is immediately removed from the WAVL tree.
  using WAVLTreeByMerkle = fbl::WAVLTree<const digest::Digest&, CacheNode*, MerkleRootTraits>;

  CachePolicy cache_policy_ = CachePolicy::EvictImmediately;

  fbl::Mutex hash_lock_ = {};
  // All 'in use' blobs.
  WAVLTreeByMerkle open_hash_ __TA_GUARDED(hash_lock_){};
  // All 'closed' blobs.
  WAVLTreeByMerkle closed_hash_ __TA_GUARDED(hash_lock_){};
  // A condition variable which is signalled whenever a CacheNode has been removed from
  // the |open_hash_|. When a CacheNode runs out of references, it exists in the |open_hash_|
  // with no strong references for a short period of time before being removed and
  // either resurrected or destroyed. This means, however, that a concurrent caller
  // trying to |Lookup()| that node may see it, but be unable to acquire it.
  // This variable lets those callers wait until SOME node has been removed from the
  // |open_hash_|, at which point their |Lookup()| may have a different result.
  fbl::ConditionVariable release_cvar_;
};

}  // namespace blobfs

#endif  // SRC_STORAGE_BLOBFS_BLOB_CACHE_H_
