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

#include "DFPlatform.h"
#include "DFAllocator.h"
#include "DFCommon.h"
#include <assert.h>
#include <stdlib.h>

typedef struct DFAllocatorBlock DFAllocatorBlock;

struct DFAllocatorBlock {
    DFAllocatorBlock *next;
    size_t used;
    size_t size;
    char ATTRIBUTE_ALIGNED(8) mem[0];
};

struct DFAllocator {
    DFAllocatorBlock *blocks;
    unsigned int blockCount;
};

DFAllocator *DFAllocatorNew(void)
{
    size_t initialSize = 1;
    DFAllocator *alc = (DFAllocator *)xmalloc(sizeof(DFAllocator));
    alc->blocks = (DFAllocatorBlock *)xmalloc(sizeof(DFAllocatorBlock)+initialSize);
    alc->blocks->next = NULL;
    alc->blocks->used = 0;
    alc->blocks->size = initialSize;
    alc->blockCount = 1;
    return alc;
}

void DFAllocatorFree(DFAllocator *alc)
{
    while (alc->blocks != NULL) {
        DFAllocatorBlock *next = alc->blocks->next;
        free(alc->blocks);
        alc->blocks = next;
    }
    free(alc);
}

void *DFAllocatorAlloc(DFAllocator *alc, size_t size)
{
    size_t remainder = size % 8;
    if (remainder != 0)
        size += (8 - remainder);
    struct DFAllocatorBlock *block = alc->blocks;
    if (size > block->size - block->used) {
        size_t newSize = block->size*2;
        while (size > newSize)
            newSize *= 2;
        block = (DFAllocatorBlock *)xmalloc(sizeof(DFAllocatorBlock)+newSize);
        block->used = 0;
        block->size = newSize;
        block->next = alc->blocks;
        alc->blocks = block;
        alc->blockCount++;
    }
    char *mem = block->mem + block->used;
    block->used += size;
    assert(block->used <= block->size);
    assert((((unsigned long)mem) % 8) == 0);
    return mem;
}
