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

#pragma once

#include <bitmap/bitmap.h>
#include <bitmap/raw-bitmap.h>
#include <bitmap/storage.h>

#include <limits.h>
#include <memory>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>

#include <fbl/algorithm.h>
#include <fbl/macros.h>
#include <zircon/assert.h>
#include <zircon/types.h>

namespace id_allocator {
#ifdef __Fuchsia__
using RawBitmap = bitmap::RawBitmapGeneric<bitmap::VmoStorage>;
#else
using RawBitmap = bitmap::RawBitmapGeneric<bitmap::DefaultStorage>;
#endif

// IdAllocator treats ids like a resource; one can reserve and free - one
// at a time.
// Internally to keep allocation and free light-weight (O(logn)), we use
// a tree like structure. Specifically, it is a 64-nary tree.
// Each node is a bit. Leaf bit represents state, reserved or not, of the id.
// Non-leaf, parent bit is set only if all the child bits are set.
//
// During allocation, we walk down a path only if a non-leaf bit is unset.
// On finding an unset leaf bit, we set the bit and recursively set it's
// parent bit only if all children bits are set.
//
// Freeing an id involves clearing the leaf bit and clearing parent bit only
// when it is set.
//
// 64-nary tree is chosen because architecture/compilers support faster first
// set/unset bit lookup (through likes of __builtin_ffs)
//
// This class is thread-compatible
//
class IdAllocator {
 public:
  DISALLOW_COPY_ASSIGN_AND_MOVE(IdAllocator);

  // Creates a new allocator to manage allocation and free of id_count number
  // of ids. On success, returns ZX_OK. This function may fail for more than
  // one reason including but not limited to too large id_count
  // (ZX_ERR_OUT_OF_RANGE).
  static zx_status_t Create(size_t id_count, std::unique_ptr<IdAllocator>* ida_out);

  // Find and allocate an id that is not busy. Returns ZX_OK on success and
  // allocated id in in *out_id*
  zx_status_t Allocate(size_t* out_id);

  // Marks given *id* as busy. Returns ZX_OK if the id was free
  zx_status_t MarkAllocated(size_t id);

  // Frees an allocated id. Returns non-ZX_OK value on error
  zx_status_t Free(size_t id);

  // Returns true if the given id is busy. All ids>=id_count_ are considered
  // free. Allows client to test state of a given id.
  bool IsBusy(size_t id) const;

  // Grows allocator in terms of how many ids it could allocate. non-ZX_OK
  // value is returned on failure.
  zx_status_t Grow(size_t size);

  // Shrinks number of ids the existing IdAllocator can allocate. It may
  // free memory associated with the allocator and may fail.
  zx_status_t Shrink(size_t id_count);

  // Reset marks all ids free in the allocator. This may change the
  // size if id_count is not same as current id_count_ and may fail
  // during allocation/free.
  zx_status_t Reset(size_t id_count);

  // Returns current count of number of ids being managed.
  size_t Size() const { return id_count_; }

  // Human readable dump of the tree.
  void Dump() const;

 private:
  IdAllocator() : id_count_(0), level_count_(0) {}

  // Returns number of bits required in a "level" for id_count ids
  size_t LevelBitCount(int8_t level) const;

  // Returns size_t rounded number of bits for a level
  size_t LevelBitCountRounded(int8_t level) const;

  // Set a bit at *bit* in *level*. Returns true if all sister bits
  // of the *bit* are set.
  bool SetBitAt(int8_t level, size_t bit);

  // Clear a bit at *bit* in *level*.
  void ClearBitAt(int8_t level, size_t bit);

  // Returns first unset bit in *level* between index base_index and
  // (base_index + kMaxChildren). Expects kMaxChildren aligned base_index.
  // Returns kMaxId if there is no unset bit in that range.
  size_t FindFirstUnset(int8_t level, size_t base_index) const;

  // Find an id which is not busy. If all ids are busy then returns
  // kIdMax
  size_t Find() const;

  // Mark a bit busy at given level.
  // Adjusts parents' state, if necessary
  void MarkBusyInternal(size_t id, int8_t level);
  // Mark a given id busy
  void MarkBusy(size_t id);

  // Mark a bit free at given level.
  // Adjusts parents' state, if necessary
  void MarkFreeInternal(size_t id, int8_t level);
  // Mark a given id free
  void MarkFree(size_t id);

  // Marks all the bits busy that are not used in addressing id_count_ bits
  // in given a level.
  void MarkUnallocatable(int8_t level);

  // Marks all the bits free that are not used in addressing id_count_ bits
  // in given a level. During Grow, this routine is used to undo all the effect
  // of MarkUnallocatable called during previous Grow/Reset
  void MarkAllAllocatable(int8_t level);

  // Grows each RawBitmap. Returns ZX_OK on success.
  zx_status_t GrowInternal(size_t id_count);

  // This is 64-nary tree. 11 levels give 2^66 addressability which is
  // sufficient on 64-bit arch.
  static const int8_t kMaxLevels = 11;

  // levels_[0] is leaf bit and levels_[n > 0] are intermediate nodes.
  // This keeps Grow simple and lets us tree grow upwards.
  RawBitmap levels_[kMaxLevels];
  size_t id_count_;
  int8_t level_count_;
};

}  // namespace id_allocator
