// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/public/cpp/environment/logging.h"
#include "mojo/services/media/common/cpp/fifo_allocator.h"

namespace mojo {
namespace media {

FifoAllocator::FifoAllocator(uint64_t size) : front_(nullptr), free_(nullptr) {
  // front_ and free_ need to be set to nullptr before calling reset.
  Reset(size);
}

FifoAllocator::~FifoAllocator() {
  DeleteFrontToBack(front_);
  DeleteFrontToBack(free_);
}

void FifoAllocator::Reset(uint64_t size) {
  MOJO_DCHECK(size < kNullOffset);
  DeleteFrontToBack(front_);
  DeleteFrontToBack(free_);
  size_ = size;
  free_ = nullptr;
  front_ = back_ = active_ = get_free(false, size, 0);
  active_->prev = nullptr;
  active_->next = nullptr;
}

uint64_t FifoAllocator::AllocateRegion(uint64_t size) {
  MOJO_DCHECK(size != 0);

  if (active_->size < size) {
    // The active region is too small. Look for one that's large enough.
    if (!AdvanceActive(size)) {
      // No unallocated regions are large enough. Can't do the allocation.
      return kNullOffset;
    }
  }

  if (active_->size == size) {
    // The active region is exactly the right size. Use it for the allocation.
    uint64_t result = active_->offset;
    active_->allocated = true;
    if (active_ == back_ && !front_->allocated) {
      // active_ was the back region and the front region isn't allocated. Make
      // the front region the new active region.
      active_ = front_;
    } else {
      // The region after active_ is allocated, so make a zero-sized
      // placeholder.
      MakeActivePlaceholder();
    }
    return result;
  }

  // The active region can accommodate this allocation with room left over.
  // Create a new region (allocated) of the requested size at the front of the
  // active region, and adjust the active region to reflect the deficit.
  MOJO_DCHECK(active_->size > size);
  Region* allocated = get_free(true, size, active_->offset);
  active_->size -= size;
  active_->offset += size;
  insert_before(allocated, active_);
  return allocated->offset;
}

void FifoAllocator::ReleaseRegion(uint64_t size, uint64_t offset) {
  // Start at active_->next. That's usually the region we're looking for.
  bool released = Release(size, offset, active_->next, nullptr) ||
                  Release(size, offset, front_, active_);
  MOJO_DCHECK(released);
}

bool FifoAllocator::Release(uint64_t size,
                            uint64_t offset,
                            Region* begin,
                            Region* end) {
  MOJO_DCHECK(begin != nullptr || end == nullptr);
  for (Region* region = begin; region != end; region = region->next) {
    if (region->offset == offset) {
      MOJO_DCHECK(region->allocated);
      MOJO_DCHECK(region->size == size);
      region->allocated = false;

      Region* prev = region->prev;
      if (prev != nullptr && !prev->allocated) {
        // Coalesce wtih the previous region.
        prev->size += region->size;
        remove(region);
        put_free(region);
        region = prev;
      }

      Region* next = region->next;
      if (next != nullptr && !next->allocated) {
        // Coalesce wtih the next region.
        next->offset = region->offset;
        next->size += region->size;
        if (active_ == region) {
          // This can happen if we coalesced the previous region.
          active_ = next;
        }
        remove(region);
        put_free(region);
      }

      return true;
    }
  }

  return false;
}

bool FifoAllocator::AdvanceActive(uint64_t size) {
  MOJO_DCHECK(size != 0);
  return AdvanceActive(size, active_->next, nullptr) ||
         AdvanceActive(size, front_, active_);
}

bool FifoAllocator::AdvanceActive(uint64_t size, Region* begin, Region* end) {
  for (Region* region = begin; region != end; region = region->next) {
    if (!region->allocated && region->size >= size) {
      if (active_->size == 0) {
        // The old active region is zero-sized. Get rid of it.
        MOJO_DCHECK(!active_->allocated);
        remove(active_);
        put_free(active_);
      }
      active_ = region;
      return true;
    }
  }
  return false;
}

void FifoAllocator::MakeActivePlaceholder() {
  // If the old active region was at the back of the list, we'll be inserting
  // at the front, so make the offset zero. We insert at the front, because it's
  // a bit more efficient and because we don't need to implement insert_after.
  Region* new_active = get_free(
      false, 0, active_ == back_ ? 0 : active_->offset + active_->size);

  MOJO_DCHECK((active_ == back_) == (active_->next == nullptr));
  insert_before(new_active, active_ == back_ ? front_ : active_->next);
  active_ = new_active;
}

void FifoAllocator::remove(Region* region) {
  MOJO_DCHECK(region);

  if (front_ == region) {
    MOJO_DCHECK(region->prev == nullptr);
    front_ = region->next;
  } else {
    MOJO_DCHECK(region->prev);
    MOJO_DCHECK(region->prev->next == region);
    region->prev->next = region->next;
  }

  if (back_ == region) {
    MOJO_DCHECK(region->next == nullptr);
    back_ = region->prev;
  } else {
    MOJO_DCHECK(region->next);
    MOJO_DCHECK(region->next->prev == region);
    region->next->prev = region->prev;
  }
}

void FifoAllocator::insert_before(Region* region, Region* before_this) {
  MOJO_DCHECK(region);
  MOJO_DCHECK(before_this);

  region->prev = before_this->prev;
  before_this->prev = region;
  region->next = before_this;
  if (front_ == before_this) {
    MOJO_DCHECK(region->prev == nullptr);
    front_ = region;
  } else {
    MOJO_DCHECK(region->prev);
    region->prev->next = region;
  }
}

FifoAllocator::Region* FifoAllocator::get_free(bool allocated,
                                               uint64_t size,
                                               uint64_t offset) {
  MOJO_DCHECK(size <= size_);
  MOJO_DCHECK(offset <= size_ - size);

  Region* result = free_;
  if (result == nullptr) {
    result = new Region();
  } else {
    free_ = free_->next;
  }

  result->allocated = allocated;
  result->size = size;
  result->offset = offset;

  return result;
}

void FifoAllocator::DeleteFrontToBack(Region* region) {
  while (region != nullptr) {
    Region* to_delete = region;
    region = region->next;
    delete to_delete;
  }
}

}  // namespace media
}  // namespace mojo
