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

#include "kudu/fs/block_manager.h"

#include <algorithm>
#include <mutex>
#include <ostream>

#include <gflags/gflags.h>
#include <glog/logging.h>

#include "kudu/gutil/integral_types.h"
#include "kudu/gutil/macros.h"
#include "kudu/gutil/strings/numbers.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/util/env.h"
#include "kudu/util/faststring.h"
#include "kudu/util/flag_tags.h"

// The default value is optimized for throughput in the case that
// there are multiple drives backing the tablet. By asynchronously
// flushing each block before issuing any fsyncs, the IO across
// disks is done in parallel.
//
// This increases throughput but can harm latency in the case that
// there are few disks and the WAL is on the same disk as the
// data blocks. The default is chosen based on the assumptions that:
// - latency is leveled across machines by Raft
// - latency-sensitive applications can devote a disk to the WAL
// - super-sensitive applications can devote an SSD to the WAL.
// - users could always change this to "never", which slows down
//   throughput but may improve write latency.
DEFINE_string(block_manager_preflush_control, "finalize",
              "Controls when to pre-flush a block. Valid values are 'finalize', "
              "'close', or 'never'. If 'finalize', blocks will be pre-flushed "
              "when writing is finished. If 'close', blocks will be pre-flushed "
              "when their transaction is committed. If 'never', blocks will "
              "never be pre-flushed but still be flushed when closed.");
TAG_FLAG(block_manager_preflush_control, experimental);

DEFINE_int64(block_manager_max_open_files, -1,
             "Maximum number of open file descriptors to be used for data "
             "blocks. If -1, Kudu will automatically calculate this value. "
             "This is a soft limit. It is an error to use a value of 0.");
TAG_FLAG(block_manager_max_open_files, advanced);
TAG_FLAG(block_manager_max_open_files, evolving);

static bool ValidateMaxOpenFiles(const char* /*flagname*/, int64_t value) {
  if (value == 0 || value < -1) {
    LOG(ERROR) << "Invalid max open files: cannot be " << value;
    return false;
  }
  return true;
}
DEFINE_validator(block_manager_max_open_files, &ValidateMaxOpenFiles);

using strings::Substitute;

namespace kudu {
namespace fs {

BlockManagerOptions::BlockManagerOptions()
  : read_only(false) {}

int64_t GetFileCacheCapacityForBlockManager(Env* env) {
  // Maximize this process' open file limit first, if possible.
  static std::once_flag once;
  std::call_once(once, [&]() {
    env->IncreaseResourceLimit(Env::ResourceLimitType::OPEN_FILES_PER_PROCESS);
  });

  uint64_t rlimit =
      env->GetResourceLimit(Env::ResourceLimitType::OPEN_FILES_PER_PROCESS);
  // See block_manager_max_open_files.
  if (FLAGS_block_manager_max_open_files == -1) {
    // Use file-max as a possible upper bound.
    faststring buf;
    uint64_t buf_val;
    if (ReadFileToString(env, "/proc/sys/fs/file-max", &buf).ok() &&
        safe_strtou64(buf.ToString(), &buf_val)) {
      rlimit = std::min(rlimit, buf_val);
    }

    // Callers of this function expect a signed 64-bit integer, so we need to
    // cap rlimit just in case it's too large.
    return std::min((2 * rlimit) / 5, static_cast<uint64_t>(kint64max));
  }
  LOG_IF(FATAL, FLAGS_block_manager_max_open_files > rlimit) <<
      Substitute(
          "Configured open file limit (block_manager_max_open_files) $0 "
          "exceeds process open file limit (ulimit) $1",
          FLAGS_block_manager_max_open_files, rlimit);
  return FLAGS_block_manager_max_open_files;
}

} // namespace fs
} // namespace kudu
