// 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 class CacheNode;

  // 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_
