/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed 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.
 */

#ifndef SRC_TRACE_PROCESSOR_SORTER_TRACE_TOKEN_BUFFER_H_
#define SRC_TRACE_PROCESSOR_SORTER_TRACE_TOKEN_BUFFER_H_

#include <cstdint>
#include <limits>
#include <optional>
#include <utility>
#include <vector>

#include "perfetto/base/compiler.h"
#include "perfetto/ext/base/circular_queue.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/trace_processor/trace_blob.h"
#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/common/parser_types.h"
#include "src/trace_processor/util/bump_allocator.h"

namespace perfetto {
namespace trace_processor {

// Helper class which stores tokenized objects while the corresponding events
// are being sorted by TraceSorter.
//
// This class intrusively compresses the tokenized objects as much as possible
// to reduce their memory footprint. This is important to reduce the peak memory
// usage of TraceProcessor which is always hit at some point during sorting.
// The tokenized objects make up the vast majority of this peak so we trade the
// complexity in this class for big reductions in the peak use.
//
// go/perfetto-tp-memory-use gives an overview of trace processor memory usage.
class TraceTokenBuffer {
 public:
  // Identifier returned when appending items to this buffer. This id can
  // later by passed to |Extract| to retrieve the event.
  struct Id {
    // The allocation id of the object in the buffer.
    BumpAllocator::AllocId alloc_id;
  };

  // Appends an object of type |T| to the token buffer. Returns an id for
  // looking up the object later using |Extract|.
  template <typename T>
  PERFETTO_WARN_UNUSED_RESULT Id Append(T object) {
    static_assert(sizeof(T) % 8 == 0, "Size must be a multiple of 8");
    static_assert(alignof(T) == 8, "Alignment must be 8");
    BumpAllocator::AllocId id = AllocAndResizeInternedVectors(sizeof(T));
    new (allocator_.GetPointer(id)) T(std::move(object));
    return Id{id};
  }
  PERFETTO_WARN_UNUSED_RESULT Id Append(TrackEventData);
  PERFETTO_WARN_UNUSED_RESULT Id Append(TracePacketData data) {
    // While in theory we could add a special case for TracePacketData, the
    // judgement call we make is that the code complexity does not justify the
    // micro-performance gain you might hope to see by avoiding the few if
    // conditions in the |TracePacketData| path.
    return Append(TrackEventData(std::move(data)));
  }

  // Extracts an object of type |T| from the token buffer using an id previously
  // returned by |Append|. This type *must* match the type added using Append.
  // Mismatching types will caused undefined behaviour.
  template <typename T>
  PERFETTO_WARN_UNUSED_RESULT T Extract(Id id) {
    T* typed_ptr = static_cast<T*>(allocator_.GetPointer(id.alloc_id));
    T object(std::move(*typed_ptr));
    typed_ptr->~T();
    allocator_.Free(id.alloc_id);
    return object;
  }

  // Returns the "past-the-end" id from the underlying allocator.
  // The main use of this function is to provide an id which is greater than
  // all ids previously returned by |Append|.
  //
  // This is similar to the |end()| function in standard library vector classes.
  BumpAllocator::AllocId PastTheEndAllocId() {
    return allocator_.PastTheEndId();
  }

  // Attempts to free any memory retained by this buffer and the underlying
  // allocator. The amount of memory free is implementation defined.
  void FreeMemory();

 private:
  struct BlobWithOffset {
    TraceBlob* blob;
    size_t offset_in_blob;
  };
  using InternedIndex = size_t;
  using BlobWithOffsets = std::vector<BlobWithOffset>;
  using SequenceStates = std::vector<PacketSequenceStateGeneration*>;

  // Functions to intern TraceBlob and PacketSequenceStateGeneration: as these
  // are often shared between packets, we can significantly reduce memory use
  // by only storing them once.
  uint32_t InternTraceBlob(InternedIndex, const TraceBlobView&);
  uint16_t InternSeqState(InternedIndex, RefPtr<PacketSequenceStateGeneration>);
  uint32_t AddTraceBlob(InternedIndex, const TraceBlobView&);

  BumpAllocator::AllocId AllocAndResizeInternedVectors(uint32_t size);
  InternedIndex GetInternedIndex(BumpAllocator::AllocId);

  BumpAllocator allocator_;
  base::CircularQueue<BlobWithOffsets> interned_blobs_;
  base::CircularQueue<SequenceStates> interned_seqs_;
};

// GCC7 does not like us declaring these inside the class so define these
// out-of-line.
template <>
PERFETTO_WARN_UNUSED_RESULT TrackEventData
    TraceTokenBuffer::Extract<TrackEventData>(Id);
template <>
PERFETTO_WARN_UNUSED_RESULT inline TracePacketData
TraceTokenBuffer::Extract<TracePacketData>(Id id) {
  // See the comment in Append(TracePacketData) for why we do this.
  return Extract<TrackEventData>(id).trace_packet_data;
}

}  // namespace trace_processor
}  // namespace perfetto

#endif  // SRC_TRACE_PROCESSOR_SORTER_TRACE_TOKEN_BUFFER_H_
