// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 KUDU_CONSENSUS_LOG_ANCHOR_REGISTRY_
#define KUDU_CONSENSUS_LOG_ANCHOR_REGISTRY_

#include <cstddef>
#include <cstdint>
#include <map>
#include <string>

#include <gtest/gtest_prod.h>

#include "kudu/gutil/macros.h"
#include "kudu/gutil/ref_counted.h"
#include "kudu/util/locks.h"
#include "kudu/util/monotime.h"
#include "kudu/util/status.h"

namespace kudu {
namespace log {

struct LogAnchor;

// This class allows callers to register their interest in (anchor) a particular
// log index. The primary use case for this is to prevent the deletion of segments of
// the WAL that reference as-yet unflushed in-memory operations.
//
// This class is thread-safe.
class LogAnchorRegistry : public RefCountedThreadSafe<LogAnchorRegistry> {
 public:
  LogAnchorRegistry();

  // Register interest for a particular log index.
  // log_index: The log index the caller wishes to anchor.
  // owner: String to describe who is registering the anchor. Used in assert
  //        messages for debugging purposes.
  // anchor: Pointer to LogAnchor structure that will be populated on registration.
  void Register(int64_t log_index, const std::string& owner, LogAnchor* anchor);

  // Register interest for a particular log index, or update an anchor if it
  // already exists.
  Status RegisterOrUpdate(int64_t log_index,
                          const std::string& owner,
                          LogAnchor* anchor);

  // Release the anchor on a log index.
  // Note: anchor must be the original pointer passed to Register().
  Status Unregister(LogAnchor* anchor);

  // Release the anchor on a log index if it is registered.
  // Otherwise, do nothing.
  Status UnregisterIfAnchored(LogAnchor* anchor);

  // Query the registry to find the earliest anchored log index in the registry.
  // Returns Status::NotFound if no anchors are currently active.
  Status GetEarliestRegisteredLogIndex(int64_t* log_index);

  // Simply returns the number of active anchors for use in debugging / tests.
  // This is _not_ a constant-time operation.
  size_t GetAnchorCountForTests() const;

  // Dumps information about registered anchors to a string.
  std::string DumpAnchorInfo() const;

 private:
  friend class RefCountedThreadSafe<LogAnchorRegistry>;
  ~LogAnchorRegistry();

  typedef std::multimap<int64_t, LogAnchor*> AnchorMultiMap;

  // Register a new anchor after taking the lock. See Register().
  void RegisterUnlocked(int64_t log_index, const std::string& owner, LogAnchor* anchor);

  // Unregister an anchor after taking the lock. See Unregister().
  Status UnregisterUnlocked(LogAnchor* anchor);

  AnchorMultiMap anchors_;
  mutable simple_spinlock lock_;

  DISALLOW_COPY_AND_ASSIGN(LogAnchorRegistry);
};

// A simple struct that allows us to keep track of which log segments we want
// to anchor (prevent log GC on).
struct LogAnchor {
 public:
  LogAnchor();
  ~LogAnchor();

 private:
  FRIEND_TEST(LogTestOptionalCompression, TestGCWithLogRunning);
  FRIEND_TEST(LogAnchorRegistryTest, TestUpdateRegistration);
  friend class LogAnchorRegistry;

  // Whether any log index is currently registered with this anchor.
  bool is_registered;

  // When this anchor was last registered or updated.
  MonoTime when_registered;

  // The index of the log entry we are anchoring on.
  int64_t log_index;

  // An arbitrary string containing details of the subsystem holding the
  // anchor, and any relevant information about it that should be displayed in
  // the log or the web UI.
  std::string owner;

  DISALLOW_COPY_AND_ASSIGN(LogAnchor);
};

// Helper class that will anchor the minimum log index recorded.
class MinLogIndexAnchorer {
 public:
  // Construct anchorer for specified registry that will register anchors with
  // the specified owner name.
  MinLogIndexAnchorer(LogAnchorRegistry* registry, std::string owner);

  // The destructor will unregister the anchor if it is registered.
  ~MinLogIndexAnchorer();

  // If op_id is less than the minimum index registered so far, or if no indexes
  // are currently registered, anchor on 'log_index'.
  void AnchorIfMinimum(int64_t log_index);

  // Un-anchors the earliest index (which is the only one tracked).
  // If no minimum is known (no anchor registered), returns OK.
  Status ReleaseAnchor();

  // Returns the first recorded log index, kInvalidOpIdIndex if there's none.
  int64_t minimum_log_index() const;

 private:
  const scoped_refptr<LogAnchorRegistry> registry_;
  const std::string owner_;
  LogAnchor anchor_;

  // The index currently anchored, or kInvalidOpIdIndex if no anchor has yet been registered.
  int64_t minimum_log_index_;
  mutable simple_spinlock lock_;

  DISALLOW_COPY_AND_ASSIGN(MinLogIndexAnchorer);
};

} // namespace log
} // namespace kudu

#endif // KUDU_CONSENSUS_LOG_ANCHOR_REGISTRY_
