Cavil-Matcher

 view release on metacpan or  search on metacpan

src/matcher.cc  view on Meta::CPAN

// SPDX-FileCopyrightText: SUSE LLC
// SPDX-License-Identifier: GPL-2.0-or-later

#include "matcher.h"

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <fcntl.h>
#include <map>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

// Same safety limit as the previous engine: lines longer than this are read in chunks by fgets, so a
// giant single-line file never overflows the buffer.
static const int MAX_LINE_SIZE = 8000;

MappedFile::~MappedFile() {
  if (_data && _data != MAP_FAILED) munmap((void*)_data, _size);
  if (_fd >= 0) close(_fd);
}

bool MappedFile::map(const std::string& path) {
  _fd = open(path.c_str(), O_RDONLY);
  if (_fd < 0) return false;
  struct stat st;
  if (fstat(_fd, &st) != 0 || st.st_size <= 0) {
    close(_fd);
    _fd = -1;
    return false;
  }
  void* p = mmap(nullptr, (size_t)st.st_size, PROT_READ, MAP_SHARED, _fd, 0);
  if (p == MAP_FAILED) {
    close(_fd);
    _fd = -1;
    return false;
  }
  _data = static_cast<const char*>(p);
  _size = (size_t)st.st_size;
  return true;
}

void Matcher::clear() {
  _build       = BuildTrie();
  _build_dirty = false;
  _build_segment = Segment();
  _segments.clear();
  _maps.clear();
  _tombstones.clear();
}

void Matcher::add_pattern(uint32_t id, const std::vector<uint64_t>& tokens) {
  _build.add_pattern(id, tokens);
  _build_dirty = true;
}

void Matcher::set_tombstones(const std::vector<uint32_t>& ids) {
  _tombstones.clear();
  for (uint32_t id : ids) _tombstones.insert(id);
}

bool Matcher::attach(const std::string& path) {
  auto mf = std::make_unique<MappedFile>();
  if (!mf->map(path)) return false;
  auto seg = std::make_unique<Segment>();
  // Trusted scan path: skip the whole-payload CRC (verified at publish), keep structural validation.
  if (!seg->open(mf->data(), mf->size(), /*verify_crc=*/false)) return false;
  _maps.push_back(std::move(mf));
  _segments.push_back(std::move(seg));
  return true;
}

bool Matcher::verify(const std::string& path) const {
  // Full integrity check (CRC + structure) of a segment file, for an explicit fsck. The scan path
  // (load/attach) trusts the CRC of the immutable published cache; this is how it is proven on demand.
  MappedFile mf;
  if (!mf.map(path)) return false;
  Segment seg;
  return seg.open(mf.data(), mf.size(), /*verify_crc=*/true);
}

bool Matcher::dump(const std::string& path) {
  std::vector<char> buf = _build.compile(_generation);

  // Publish is the one place integrity is proven: full-verify (CRC + structure) the freshly compiled
  // buffer before it is written, so the scan path can safely trust this immutable file without re-CRCing
  // it on every open. A buffer that fails here is never published.



( run in 3.340 seconds using v1.01-cache-2.11-cpan-14f38c9f855 )