// 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.
// This file is copied from
// https://github.com/apache/impala/blob/branch-2.9.0/be/src/util/bitmap.cpp
// and modified by Doris

#include "util/bitmap.h"

#include <sstream>
namespace doris {

std::string Bitmap::DebugString(bool print_bits) const {
    int64_t words = BitUtil::round_up(num_bits_, 64) / 64;
    std::stringstream ss;
    ss << "Size (" << num_bits_ << ") words (" << words << ") ";
    if (print_bits) {
        for (int i = 0; i < num_bits(); ++i) {
            if (Get(i)) {
                ss << "1";
            } else {
                ss << "0";
            }
        }
    } else {
        for (auto v : buffer_) {
            ss << v << ".";
        }
    }
    ss << std::endl;
    return ss.str();
}

void BitmapChangeBits(uint8_t* bitmap, size_t offset, size_t num_bits, bool value) {
    DCHECK_GT(num_bits, 0);

    size_t start_byte = (offset >> 3);
    size_t end_byte = (offset + num_bits - 1) >> 3;
    int single_byte = (start_byte == end_byte);

    // Change the last bits of the first byte
    size_t left = offset & 0x7;
    size_t right = (single_byte) ? (left + num_bits) : 8;
    uint8_t mask = ((0xff << left) & (0xff >> (8 - right)));
    if (value) {
        bitmap[start_byte++] |= mask;
    } else {
        bitmap[start_byte++] &= ~mask;
    }

    // Nothing left... I'm done
    if (single_byte) {
        return;
    }

    // change the middle bits
    if (end_byte > start_byte) {
        const uint8_t pattern8[2] = {0x00, 0xff};
        memset(bitmap + start_byte, pattern8[value], end_byte - start_byte);
    }

    // change the first bits of the last byte
    right = offset + num_bits - (end_byte << 3);
    mask = (0xff >> (8 - right));
    if (value) {
        bitmap[end_byte] |= mask;
    } else {
        bitmap[end_byte] &= ~mask;
    }
}

bool BitmapFindFirst(const uint8_t* bitmap, size_t offset, size_t bitmap_size, bool value,
                     size_t* idx) {
    const uint64_t pattern64[2] = {0xffffffffffffffff, 0x0000000000000000};
    const uint8_t pattern8[2] = {0xff, 0x00};
    size_t bit;

    DCHECK_LE(offset, bitmap_size);

    // Jump to the byte at specified offset
    const uint8_t* p = bitmap + (offset >> 3);
    size_t num_bits = bitmap_size - offset;

    // Find a 'value' bit at the end of the first byte
    if ((bit = offset & 0x7)) {
        for (; bit < 8 && num_bits > 0; ++bit) {
            if (BitmapTest(p, bit) == value) {
                *idx = ((p - bitmap) << 3) + bit;
                return true;
            }

            num_bits--;
        }

        p++;
    }

    // check 64bit at the time for a 'value' bit
    const uint64_t* u64 = (const uint64_t*)p;
    while (num_bits >= 64 && *u64 == pattern64[value]) {
        num_bits -= 64;
        u64++;
    }

    // check 8bit at the time for a 'value' bit
    p = (const uint8_t*)u64;
    while (num_bits >= 8 && *p == pattern8[value]) {
        num_bits -= 8;
        p++;
    }

    // Find a 'value' bit at the beginning of the last byte
    for (bit = 0; num_bits > 0; ++bit) {
        if (BitmapTest(p, bit) == value) {
            *idx = ((p - bitmap) << 3) + bit;
            return true;
        }
        num_bits--;
    }

    return false;
}

} // namespace doris
