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

// This file contains the implementation of IdAllocator.

#include "gpu/command_buffer/common/id_allocator.h"

#include <stdint.h>

#include <limits>
#include "base/check.h"

namespace gpu {

IdAllocator::IdAllocator() {
  static_assert(kInvalidResource == 0u, "kInvalidResource must be 0");
  // Simplify the code by making sure that lower_bound(id) never
  // returns the beginning of the map, if id is valid (eg !=
  // kInvalidResource).
  used_ids_.insert(std::make_pair(0u, 0u));
}

IdAllocator::~IdAllocator() = default;

ResourceId IdAllocator::AllocateID() {
  return AllocateIDRange(1u);
}

ResourceId IdAllocator::AllocateIDAtOrAbove(ResourceId desired_id) {
  if (desired_id == 0u || desired_id == 1u) {
    return AllocateIDRange(1u);
  }

  ResourceIdRangeMap::iterator current = used_ids_.lower_bound(desired_id);
  ResourceIdRangeMap::iterator next = current;
  if (current == used_ids_.end() || current->first > desired_id) {
    current--;
  } else {
    next++;
  }

  ResourceId first_id = current->first;
  ResourceId last_id = current->second;

  DCHECK(desired_id >= first_id);

  if (desired_id - 1u <= last_id) {
    // Append to current range.
    last_id++;
    if (last_id == 0) {
      // The increment overflowed.
      return AllocateIDRange(1u);
    }

    current->second = last_id;

    if (next != used_ids_.end() && next->first - 1u == last_id) {
      // Merge with next range.
      current->second = next->second;
      used_ids_.erase(next);
    }
    return last_id;
  } else if (next != used_ids_.end() && next->first - 1u == desired_id) {
    // Prepend to next range.
    ResourceId last_existing_id = next->second;
    used_ids_.erase(next);
    used_ids_.insert(std::make_pair(desired_id, last_existing_id));
    return desired_id;
  }
  used_ids_.insert(std::make_pair(desired_id, desired_id));
  return desired_id;
}

ResourceId IdAllocator::AllocateIDRange(uint32_t range) {
  DCHECK(range > 0u);

  ResourceIdRangeMap::iterator current = used_ids_.begin();
  ResourceIdRangeMap::iterator next = current;

  while (++next != used_ids_.end()) {
    if (next->first - current->second > range) {
      break;
    }
    current = next;
  }

  ResourceId first_id = current->second + 1u;
  ResourceId last_id = first_id + range - 1u;

  if (first_id == 0u || last_id < first_id) {
    return kInvalidResource;
  }

  current->second = last_id;

  if (next != used_ids_.end() && next->first - 1u == last_id) {
    // Merge with next range.
    current->second = next->second;
    used_ids_.erase(next);
  }

  return first_id;
}

bool IdAllocator::MarkAsUsed(ResourceId id) {
  DCHECK(id);
  ResourceIdRangeMap::iterator current = used_ids_.lower_bound(id);
  if (current != used_ids_.end() && current->first == id) {
    return false;
  }

  ResourceIdRangeMap::iterator next = current;
  --current;

  if (current->second >= id) {
    return false;
  }

  DCHECK(current->first < id && current->second < id);

  if (current->second + 1u == id) {
    // Append to current range.
    current->second = id;
    if (next != used_ids_.end() && next->first - 1u == id) {
      // Merge with next range.
      current->second = next->second;
      used_ids_.erase(next);
    }
    return true;
  } else if (next != used_ids_.end() && next->first - 1u == id) {
    // Prepend to next range.
    ResourceId last_existing_id = next->second;
    used_ids_.erase(next);
    used_ids_.insert(std::make_pair(id, last_existing_id));
    return true;
  }

  used_ids_.insert(std::make_pair(id, id));
  return true;
}

void IdAllocator::FreeID(ResourceId id) {
  FreeIDRange(id, 1u);
}

void IdAllocator::FreeIDRange(ResourceId first_id, uint32_t range) {
  static_assert(kInvalidResource == 0u, "kInvalidResource must be 0");

  if (range == 0u || (first_id == 0u && range == 1u)) {
    return;
  }

  if (first_id == 0u) {
    first_id++;
    range--;
  }

  ResourceId last_id = first_id + range - 1u;
  if (last_id < first_id) {
    last_id = std::numeric_limits<ResourceId>::max();
  }

  while (true) {
    ResourceIdRangeMap::iterator current = used_ids_.lower_bound(last_id);
    if (current == used_ids_.end() || current->first > last_id) {
      --current;
    }

    if (current->second < first_id) {
      return;
    }

    if (current->first >= first_id) {
      ResourceId last_existing_id = current->second;
      used_ids_.erase(current);
      if (last_id < last_existing_id) {
        used_ids_.insert(std::make_pair(last_id + 1u, last_existing_id));
      }
    } else if (current->second <= last_id) {
      current->second = first_id - 1u;
    } else {
      DCHECK(current->first < first_id && current->second > last_id);
      ResourceId last_existing_id = current->second;
      current->second = first_id - 1u;
      used_ids_.insert(std::make_pair(last_id + 1u, last_existing_id));
    }
  }
}

bool IdAllocator::InUse(ResourceId id) const {
  if (id == kInvalidResource) {
    return false;
  }

  ResourceIdRangeMap::const_iterator current = used_ids_.lower_bound(id);
  if (current != used_ids_.end()) {
    if (current->first == id) {
      return true;
    }
  }

  --current;
  return current->second >= id;
}

}  // namespace gpu
