/* 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"

#if !defined(STARBOARD)
#include <stdlib.h>  /* free, malloc, exit */
#include <string.h>  /* memcpy, memset */
#else
#include "starboard/client_porting/poem/stdio_poem.h"
#include "starboard/client_porting/poem/string_poem.h"
#endif

#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)

static void* DefaultAllocFunc(void* opaque, size_t size) {
  BROTLI_UNUSED(opaque);
  return malloc(size);
}

static void DefaultFreeFunc(void* opaque, void* address) {
  BROTLI_UNUSED(opaque);
  free(address);
}

void BrotliInitMemoryManager(
    MemoryManager* m, brotli_alloc_func alloc_func, brotli_free_func free_func,
    void* opaque) {
  if (!alloc_func) {
    m->alloc_func = DefaultAllocFunc;
    m->free_func = DefaultFreeFunc;
    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
