// Copyright 2016 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 <bitmap/raw-bitmap.h>
#include <bitmap/storage.h>

#include <limits.h>
#include <stddef.h>

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

namespace bitmap {
namespace {

// Translates a bit offset into a starting index in the bitmap array.
constexpr size_t FirstIdx(size_t bitoff) {
    return bitoff / kBits;
}

// GetMask returns a 64-bit bitmask. If the block of the bitmap we're looking
// at isn't the first or last, all bits are set.  Otherwise, the bits outside of
// [off,max) are cleared.  Bits are counted with the LSB as 0 and the MSB as 63.
//
// Examples:
//  GetMask(false, false, 16, 48) => 0xffffffffffffffff
//  GetMask(true,  false, 16, 48) => 0xffffffffffff0000
//  GetMask(false,  true, 16, 48) => 0x0000ffffffffffff
//  GetMask(true,   true, 16, 48) => 0x0000ffffffff0000
size_t GetMask(bool first, bool last, size_t off, size_t max) {
    size_t ones = ~(size_t(0));
    size_t mask = ones;
    if (first) {
        mask &= ones << (off % kBits);
    }
    if (last) {
        mask &= ones >> ((kBits - (max % kBits)) % kBits);
    }
    return mask;
}

// Applies a bitmask to the given data value. The result value has bits set
// which fall within the mask but do not match is_set.
size_t MaskBits(size_t data, size_t idx, size_t bitoff, size_t bitmax,
                bool is_set) {
    size_t mask = GetMask(idx == FirstIdx(bitoff), idx == LastIdx(bitmax),
                          bitoff, bitmax);
    if (is_set) {
        // If is_set=true, invert the mask, OR it with the value, and invert
        // it again to hopefully get all zeros.
        return ~(~mask | data);
    } else {
        // If is_set=false, just AND the mask with the value to hopefully
        // get all zeros.
        return mask & data;
    }
}

// Counts the number of zeros.  It assumes everything in the array up to
// bits_[idx] is zero.
#if (SIZE_MAX == UINT_MAX)
#define CLZ(x) (x == 0 ? kBits : __builtin_clz(x))
#define CTZ(x) (x == 0 ? kBits : __builtin_ctz(x))
#elif (SIZE_MAX == ULONG_MAX)
#define CLZ(x) (x == 0 ? kBits : __builtin_clzl(x))
#define CTZ(x) (x == 0 ? kBits : __builtin_ctzl(x))
#elif (SIZE_MAX == ULLONG_MAX)
#define CLZ(x) (x == 0 ? kBits : __builtin_clzll(x))
#define CTZ(x) (x == 0 ? kBits : __builtin_ctzll(x))
#else
#error "Unsupported size_t length"
#endif

} // namespace

zx_status_t RawBitmapBase::Shrink(size_t size) {
    if (size > size_) {
        return ZX_ERR_NO_MEMORY;
    }
    size_ = size;
    return ZX_OK;
}

bool RawBitmapBase::Scan(size_t bitoff, size_t bitmax, bool is_set,
                         size_t* out) const {
    bitmax = fbl::min(bitmax, size_);
    if (bitoff >= bitmax) {
        return true;
    }
    size_t i = FirstIdx(bitoff);
    while (true) {
        size_t masked = MaskBits(data_[i], i, bitoff, bitmax, is_set);
        if (masked != 0) {
            if (out) {
                *out = i * bitmap::kBits + CTZ(masked);
            }
            return false;
        }
        if (i == LastIdx(bitmax)) {
            return true;
        }
        ++i;
    }
}

bool RawBitmapBase::ReverseScan(size_t bitoff, size_t bitmax, bool is_set,
                                size_t* out) const {
    bitmax = fbl::min(bitmax, size_);
    if (bitoff >= bitmax) {
        return true;
    }
    size_t i = LastIdx(bitmax);
    while (true) {
        size_t masked = MaskBits(data_[i], i, bitoff, bitmax, is_set);
        if (masked != 0) {
            if (out) {
                *out = (i + 1) * bitmap::kBits - (CLZ(masked) + 1);
            }
            return false;
        }
        if (i == FirstIdx(bitoff)) {
            return true;
        }
        --i;
    }
}

zx_status_t RawBitmapBase::Find(bool is_set, size_t bitoff, size_t bitmax,
                                size_t run_len, size_t* out) const {
    if (!out || bitmax <= bitoff) {
        return ZX_ERR_INVALID_ARGS;
    }
    size_t start = bitoff;
    while (true) {
        if (Scan(bitoff, bitmax, !is_set, &start) ||
            (bitmax - start < run_len)) {
            return ZX_ERR_NO_RESOURCES;
        }
        if (Scan(start, start + run_len, is_set, &bitoff)) {
            *out = start;
            return ZX_OK;
        }
    }
}

zx_status_t RawBitmapBase::ReverseFind(bool is_set, size_t bitoff, size_t bitmax,
                                 size_t run_len, size_t* out) const {
    if (!out || bitmax <= bitoff) {
        return ZX_ERR_INVALID_ARGS;
    }
    size_t start = bitmax;
    while (true) {
        if (ReverseScan(bitoff, bitmax, !is_set, &start)) {
            return ZX_ERR_NO_RESOURCES;
        }
        // Increment start to be last bit that is !is_set
        ++start;
        if ((start - bitoff < run_len)) {
            return ZX_ERR_NO_RESOURCES;
        }
        if (ReverseScan(start - run_len, start, is_set, &bitmax)) {
            *out = start - run_len;
            return ZX_OK;
        }
    }
}

bool RawBitmapBase::Get(size_t bitoff, size_t bitmax, size_t* first) const {
    bool result;
    if ((result = Scan(bitoff, bitmax, true, first)) && first) {
        *first = bitmax;
    }
    return result;
}

zx_status_t RawBitmapBase::Set(size_t bitoff, size_t bitmax) {
    if (bitoff > bitmax || bitmax > size_) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (bitoff == bitmax) {
        return ZX_OK;
    }
    size_t first_idx = FirstIdx(bitoff);
    size_t last_idx = LastIdx(bitmax);
    for (size_t i = first_idx; i <= last_idx; ++i) {
        data_[i] |= GetMask(i == first_idx, i == last_idx, bitoff, bitmax);
    }
    return ZX_OK;
}

zx_status_t RawBitmapBase::Clear(size_t bitoff, size_t bitmax) {
    if (bitoff > bitmax || bitmax > size_) {
        return ZX_ERR_INVALID_ARGS;
    }
    if (bitoff == bitmax) {
        return ZX_OK;
    }
    size_t first_idx = FirstIdx(bitoff);
    size_t last_idx = LastIdx(bitmax);
    for (size_t i = first_idx; i <= last_idx; ++i) {
        data_[i] &= ~(GetMask(i == first_idx, i == last_idx, bitoff, bitmax));
    }
    return ZX_OK;
}

void RawBitmapBase::ClearAll() {
    if (size_ == 0) {
        return;
    }
    size_t last_idx = LastIdx(size_);
    for (size_t i = 0; i <= last_idx; ++i) {
        data_[i] = 0;
    }
}

} // namespace bitmap
