Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3215fd93 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "[zip] Save 1 malloc and memset for each added file in ZipWriter"

parents 02427f5f a6633d77
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ static void FindEntry_no_match(benchmark::State& state) {
  std::string_view name("thisFileNameDoesNotExist");

  // Start the benchmark.
  while (state.KeepRunning()) {
  for (auto _ : state) {
    OpenArchive(temp_file->path, &handle);
    FindEntry(handle, name, &data);
    CloseArchive(handle);
@@ -73,7 +73,7 @@ static void Iterate_all_files(benchmark::State& state) {
  ZipEntry data;
  std::string name;

  while (state.KeepRunning()) {
  for (auto _ : state) {
    OpenArchive(temp_file->path, &handle);
    StartIteration(handle, &iteration_cookie);
    while (Next(iteration_cookie, &data, &name) == 0) {
@@ -84,4 +84,27 @@ static void Iterate_all_files(benchmark::State& state) {
}
BENCHMARK(Iterate_all_files);

static void StartAlignedEntry(benchmark::State& state) {
  TemporaryFile file;
  FILE* fp = fdopen(file.fd, "w");

  ZipWriter writer(fp);

  auto alignment = uint32_t(state.range(0));
  std::string name = "name";
  int counter = 0;
  for (auto _ : state) {
    writer.StartAlignedEntry(name + std::to_string(counter++), 0, alignment);
    state.PauseTiming();
    writer.WriteBytes("hola", 4);
    writer.FinishEntry();
    state.ResumeTiming();
  }

  writer.Finish();
  fclose(fp);
}
BENCHMARK(StartAlignedEntry)->Arg(2)->Arg(16)->Arg(1024)->Arg(4096);


BENCHMARK_MAIN();
+14 −3
Original line number Diff line number Diff line
@@ -247,13 +247,24 @@ int32_t ZipWriter::StartAlignedEntryWithTime(std::string_view path, size_t flags
  ExtractTimeAndDate(time, &file_entry.last_mod_time, &file_entry.last_mod_date);

  off_t offset = current_offset_ + sizeof(LocalFileHeader) + file_entry.path.size();
  std::vector<char> zero_padding;
  // prepare a pre-zeroed memory page in case when we need to pad some aligned data.
  static constexpr auto kPageSize = 4096;
  static constexpr char kSmallZeroPadding[kPageSize] = {};
  // use this buffer if our preallocated one is too small
  std::vector<char> zero_padding_big;
  const char* zero_padding = nullptr;

  if (alignment != 0 && (offset & (alignment - 1))) {
    // Pad the extra field so the data will be aligned.
    uint16_t padding = static_cast<uint16_t>(alignment - (offset % alignment));
    file_entry.padding_length = padding;
    offset += padding;
    zero_padding.resize(padding, 0);
    if (padding <= std::size(kSmallZeroPadding)) {
        zero_padding = kSmallZeroPadding;
    } else {
        zero_padding_big.resize(padding, 0);
        zero_padding = zero_padding_big.data();
    }
  }

  LocalFileHeader header = {};
@@ -269,7 +280,7 @@ int32_t ZipWriter::StartAlignedEntryWithTime(std::string_view path, size_t flags
    return HandleError(kIoError);
  }

  if (file_entry.padding_length != 0 && fwrite(zero_padding.data(), 1, file_entry.padding_length,
  if (file_entry.padding_length != 0 && fwrite(zero_padding, 1, file_entry.padding_length,
                                               file_) != file_entry.padding_length) {
    return HandleError(kIoError);
  }