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

#include "f2fs.h"

namespace f2fs {

uint32_t SegMgr::GetGcCost(uint32_t segno, VictimSelPolicy *p) {
  if (p->alloc_mode == AllocMode::kSSR)
    return SegMgr::GetSegEntry(segno)->ckpt_valid_blocks;

  ZX_ASSERT(0);
#if 0  // porting needed
  /* alloc_mode == kLFS */
  if (p->gc_mode == kGcGreedy)
    return get_valid_blocks(sbi, segno, sbi->segs_per_sec);
  else
    return get_cb_cost(sbi, segno);
#endif
}

void SegMgr::SelectPolicy(GcType gc_type, CursegType type, VictimSelPolicy *p) {
  SbInfo &sbi = fs_->GetSbInfo();
  DirtySeglistInfo *dirty_i = GetDirtyInfo(&sbi);

  if (p->alloc_mode == AllocMode::kSSR) {
    p->gc_mode = GcMode::kGcGreedy;
    p->dirty_segmap = dirty_i->dirty_segmap[static_cast<int>(type)];
    p->ofs_unit = 1;
  } else {
    ZX_ASSERT(0);
#if 0  // porting needed
  p->gc_mode = select_gc_type(gc_type);
  p->dirty_segmap = dirty_i->dirty_segmap[DIRTY];
  p->ofs_unit = sbi->segs_per_sec;
#endif
  }

  p->offset = sbi.last_victim[static_cast<int>(p->gc_mode)];
}

uint32_t SegMgr::GetMaxCost(VictimSelPolicy *p) {
  SbInfo &sbi = fs_->GetSbInfo();

  if (p->gc_mode == GcMode::kGcGreedy)
    return (1 << sbi.log_blocks_per_seg) * p->ofs_unit;
  else if (p->gc_mode == GcMode::kGcCb)
    return kUint32Max;
  return 0;
}

bool SegMgr::GetVictimByDefault(GcType gc_type, CursegType type, AllocMode alloc_mode,
                                uint32_t *out) {
  SbInfo &sbi = fs_->GetSbInfo();
  DirtySeglistInfo *dirty_i = GetDirtyInfo(&sbi);
  VictimSelPolicy p;

  p.alloc_mode = alloc_mode;
  SelectPolicy(gc_type, type, &p);

  p.min_segno = kNullSegNo;
  p.min_cost = GetMaxCost(&p);

  fbl::AutoLock lock(&dirty_i->seglist_lock);

#if 0  // porting needed
	if (p.alloc_mode == AllocMode::kLFS && gc_type == GcType::kFgGC) {
		p.min_segno = check_bg_victims(sbi);
		if (p.min_segno != kNullSegNo)
			goto got_it;
	}
#endif

  uint32_t nsearched = 0;

  while (1) {
    uint32_t segno = find_next_bit_le(p.dirty_segmap, TotalSegs(&sbi), p.offset);
    if (segno >= TotalSegs(&sbi)) {
      if (sbi.last_victim[static_cast<int>(p.gc_mode)]) {
        sbi.last_victim[static_cast<int>(p.gc_mode)] = 0;
        p.offset = 0;
        continue;
      }
      break;
    }
    p.offset = ((segno / p.ofs_unit) * p.ofs_unit) + p.ofs_unit;

    if (test_bit(segno, dirty_i->victim_segmap[static_cast<int>(GcType::kFgGc)]))
      continue;
    if (gc_type == GcType::kBgGc &&
        test_bit(segno, dirty_i->victim_segmap[static_cast<int>(GcType::kBgGc)]))
      continue;
    if (IsCurSec(&sbi, GetSecNo(&sbi, segno)))
      continue;

    uint32_t cost = GetGcCost(segno, &p);

    if (p.min_cost > cost) {
      p.min_segno = segno;
      p.min_cost = cost;
    }

    if (cost == GetMaxCost(&p))
      continue;

    if (nsearched++ >= kMaxSearchLimit) {
      sbi.last_victim[static_cast<int>(p.gc_mode)] = segno;
      break;
    }
  }
#if 0  // porting needed
got_it:
#endif
  if (p.min_segno != kNullSegNo) {
    *out = (p.min_segno / p.ofs_unit) * p.ofs_unit;
    if (p.alloc_mode == AllocMode::kLFS) {
      for (uint32_t i = 0; i < p.ofs_unit; i++)
        set_bit(*out + i, dirty_i->victim_segmap[static_cast<int>(gc_type)]);
    }
  }

  return (p.min_segno == kNullSegNo) ? false : true;
}

}  // namespace f2fs
