// Copyright 2019 Google LLC.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

#include "include/private/SkContainers.h"

#include "include/core/SkSpan.h"
#include "include/core/SkTypes.h"
#include "include/private/SkMalloc.h"
#include "include/private/SkTArray.h"

#include <algorithm>
#include <cstddef>

#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
#include <malloc/malloc.h>
#elif defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX)
#include <malloc.h>
#elif defined(SK_BUILD_FOR_WIN)
#include <malloc.h>
#endif

namespace {
// Return at least as many bytes to keep malloc aligned.
constexpr size_t kMinBytes = alignof(max_align_t);

SkSpan<std::byte> complete_size(void* ptr, size_t size) {
    if (ptr == nullptr) {
        return {};
    }

    size_t completeSize = size;

    // Use the OS specific calls to find the actual capacity.
    #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
        // TODO: remove the max, when the chrome implementation of malloc_size doesn't return 0.
        completeSize = std::max(malloc_size(ptr), size);
    #elif defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 17
        completeSize = malloc_usable_size(ptr);
        SkASSERT(completeSize >= size);
    #elif defined(SK_BUILD_FOR_UNIX)
        completeSize = malloc_usable_size(ptr);
        SkASSERT(completeSize >= size);
    #elif defined(SK_BUILD_FOR_WIN)
        completeSize = _msize(ptr);
        SkASSERT(completeSize >= size);
    #endif

    return {static_cast<std::byte*>(ptr), completeSize};
}
}  // namespace

SkSpan<std::byte> SkContainerAllocator::allocate(int capacity, double growthFactor) {
    SkASSERT(capacity >= 0);
    SkASSERT(growthFactor >= 1.0);
    SkASSERT_RELEASE(capacity <= fMaxCapacity);

    if (growthFactor > 1.0 && capacity > 0) {
        capacity = this->growthFactorCapacity(capacity, growthFactor);
    }

    return sk_allocate_throw(capacity * fSizeOfT);
}

size_t SkContainerAllocator::roundUpCapacity(int64_t capacity) const {
    SkASSERT(capacity >= 0);

    // If round will not go above fMaxCapacity return rounded capacity.
    if (capacity < fMaxCapacity - kCapacityMultiple) {
        return SkAlignTo(capacity, kCapacityMultiple);
    }

    return SkToSizeT(fMaxCapacity);
}

size_t SkContainerAllocator::growthFactorCapacity(int capacity, double growthFactor) const {
    SkASSERT(capacity >= 0);
    SkASSERT(growthFactor >= 1.0);
    // Multiply by the growthFactor. Remember this must be done in 64-bit ints and not
    // size_t because size_t changes.
    const int64_t capacityGrowth = static_cast<int64_t>(capacity * growthFactor);

    // Notice that for small values of capacity, rounding up will provide most of the growth.
    return this->roundUpCapacity(capacityGrowth);
}


SkSpan<std::byte> sk_allocate_canfail(size_t size) {
    // Make sure to ask for at least the minimum number of bytes.
    const size_t adjustedSize = std::max(size, kMinBytes);
    void* ptr = sk_malloc_canfail(adjustedSize);
    return complete_size(ptr, adjustedSize);
}

SkSpan<std::byte> sk_allocate_throw(size_t size) {
    if (size == 0) {
        return {};
    }
    // Make sure to ask for at least the minimum number of bytes.
    const size_t adjustedSize = std::max(size, kMinBytes);
    void* ptr = sk_malloc_throw(adjustedSize);
    return complete_size(ptr, adjustedSize);
}
