/* Copyright 2015 Google Inc. All Rights Reserved.

   Distributed under MIT license.
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/

/* Algorithms for distributing the literals and commands of a metablock between
   block types and contexts. */

#include "./memory.h"

#include <stdlib.h>  /* exit, free, malloc */
#include <string.h>  /* memcpy */

#include "../common/platform.h"
#include <brotli/types.h>

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

#define MAX_PERM_ALLOCATED 128
#define MAX_NEW_ALLOCATED 64
#define MAX_NEW_FREED 64

#define PERM_ALLOCATED_OFFSET 0
#define NEW_ALLOCATED_OFFSET MAX_PERM_ALLOCATED
#define NEW_FREED_OFFSET (MAX_PERM_ALLOCATED + MAX_NEW_ALLOCATED)

void BrotliInitMemoryManager(
    MemoryManager* m, brotli_alloc_func alloc_func, brotli_free_func free_func,
    void* opaque) {
  if (!alloc_func) {
    m->alloc_func = BrotliDefaultAllocFunc;
    m->free_func = BrotliDefaultFreeFunc;
    m->opaque = 0;
  } else {
    m->alloc_func = alloc_func;
    m->free_func = free_func;
    m->opaque = opaque;
  }
#if !defined(BROTLI_ENCODER_EXIT_ON_OOM)
  m->is_oom = BROTLI_FALSE;
  m->perm_allocated = 0;
  m->new_allocated = 0;
  m->new_freed = 0;
#endif  /* BROTLI_ENCODER_EXIT_ON_OOM */
}

#if defined(BROTLI_ENCODER_EXIT_ON_OOM)

void* BrotliAllocate(MemoryManager* m, size_t n) {
  void* result = m->alloc_func(m->opaque, n);
  if (!result) exit(EXIT_FAILURE);
  return result;
}

void BrotliFree(MemoryManager* m, void* p) {
  m->free_func(m->opaque, p);
}

void BrotliWipeOutMemoryManager(MemoryManager* m) {
  BROTLI_UNUSED(m);
}

#else  /* BROTLI_ENCODER_EXIT_ON_OOM */

static void SortPointers(void** items, const size_t n) {
  /* Shell sort. */
  static const size_t gaps[] = {23, 10, 4, 1};
  int g = 0;
  for (; g < 4; ++g) {
    size_t gap = gaps[g];
    size_t i;
    for (i = gap; i < n; ++i) {
      size_t j = i;
      void* tmp = items[i];
      for (; j >= gap && tmp < items[j - gap]; j -= gap) {
        items[j] = items[j - gap];
      }
      items[j] = tmp;
    }
  }
}

static size_t Annihilate(void** a, size_t a_len, void** b, size_t b_len) {
  size_t a_read_index = 0;
  size_t b_read_index = 0;
  size_t a_write_index = 0;
  size_t b_write_index = 0;
  size_t annihilated = 0;
  while (a_read_index < a_len && b_read_index < b_len) {
    if (a[a_read_index] == b[b_read_index]) {
      a_read_index++;
      b_read_index++;
      annihilated++;
    } else if (a[a_read_index] < b[b_read_index]) {
      a[a_write_index++] = a[a_read_index++];
    } else {
      b[b_write_index++] = b[b_read_index++];
    }
  }
  while (a_read_index < a_len) a[a_write_index++] = a[a_read_index++];
  while (b_read_index < b_len) b[b_write_index++] = b[b_read_index++];
  return annihilated;
}

static void CollectGarbagePointers(MemoryManager* m) {
  size_t annihilated;
  SortPointers(m->pointers + NEW_ALLOCATED_OFFSET, m->new_allocated);
  SortPointers(m->pointers + NEW_FREED_OFFSET, m->new_freed);
  annihilated = Annihilate(
      m->pointers + NEW_ALLOCATED_OFFSET, m->new_allocated,
      m->pointers + NEW_FREED_OFFSET, m->new_freed);
  m->new_allocated -= annihilated;
  m->new_freed -= annihilated;

  if (m->new_freed != 0) {
    annihilated = Annihilate(
        m->pointers + PERM_ALLOCATED_OFFSET, m->perm_allocated,
        m->pointers + NEW_FREED_OFFSET, m->new_freed);
    m->perm_allocated -= annihilated;
    m->new_freed -= annihilated;
    BROTLI_DCHECK(m->new_freed == 0);
  }

  if (m->new_allocated != 0) {
    BROTLI_DCHECK(m->perm_allocated + m->new_allocated <= MAX_PERM_ALLOCATED);
    memcpy(m->pointers + PERM_ALLOCATED_OFFSET + m->perm_allocated,
           m->pointers + NEW_ALLOCATED_OFFSET,
           sizeof(void*) * m->new_allocated);
    m->perm_allocated += m->new_allocated;
    m->new_allocated = 0;
    SortPointers(m->pointers + PERM_ALLOCATED_OFFSET, m->perm_allocated);
  }
}

void* BrotliAllocate(MemoryManager* m, size_t n) {
  void* result = m->alloc_func(m->opaque, n);
  if (!result) {
    m->is_oom = BROTLI_TRUE;
    return NULL;
  }
  if (m->new_allocated == MAX_NEW_ALLOCATED) CollectGarbagePointers(m);
  m->pointers[NEW_ALLOCATED_OFFSET + (m->new_allocated++)] = result;
  return result;
}

void BrotliFree(MemoryManager* m, void* p) {
  if (!p) return;
  m->free_func(m->opaque, p);
  if (m->new_freed == MAX_NEW_FREED) CollectGarbagePointers(m);
  m->pointers[NEW_FREED_OFFSET + (m->new_freed++)] = p;
}

void BrotliWipeOutMemoryManager(MemoryManager* m) {
  size_t i;
  CollectGarbagePointers(m);
  /* Now all unfreed pointers are in perm-allocated list. */
  for (i = 0; i < m->perm_allocated; ++i) {
    m->free_func(m->opaque, m->pointers[PERM_ALLOCATED_OFFSET + i]);
  }
  m->perm_allocated = 0;
}

#endif  /* BROTLI_ENCODER_EXIT_ON_OOM */

#if defined(__cplusplus) || defined(c_plusplus)
}  /* extern "C" */
#endif
