<commit_before>#include "macros.h"
#include "txn.h"
#include "dbcore/sm-rep.h"
#include "dbcore/serial.h"

#include <atomic>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
#include <utility>

#if defined(SSN) || defined(SSI)
static __thread transaction::read_set_t *tls_read_set;
#endif

extern write_set_t tls_write_set[config::MAX_THREADS];

transaction::transaction(uint64_t flags, str_arena &sa)
    : flags(flags), sa(&sa), write_set(tls_write_set[thread::my_id()]) {
  if (config::is_backup_srv()) {
    // Read-only transaction on backup - grab a begin timestamp and go.
    // A read-only 'transaction' on a backup basically is reading a
    // consistent snapshot back in time. No CC involved.
    thread_local xid_context *ctx = nullptr;
    if (!ctx) {
      ctx = xid_get_context(xid_alloc());
    }
    xc = ctx;
    RCU::rcu_enter();
    xc->begin = volatile_read(*rep::global_persisted_lsn_ptr);
    ASSERT(xc->begin);
  } else {
    initialize_read_write();
  }
}

void transaction::initialize_read_write() {
  if (config::phantom_prot) {
    absent_set.set_empty_key(NULL);  // google dense map
    absent_set.clear();
  }
  write_set.clear();
#if defined(SSN) || defined(SSI)
  if (unlikely(not tls_read_set)) {
    tls_read_set = new read_set_t;
    tls_read_set->reserve(2000);
  }
  read_set = tls_read_set;
  read_set->clear();
#endif
  xid = TXN::xid_alloc();
  xc = xid_get_context(xid);
  xc->begin_epoch = MM::epoch_enter();
#if defined(SSN) || defined(SSI)
  xc->xct = this;<commit_msg>Fix read-only transaction begin timestamp on read replicas.<commit_after>#include "macros.h"
#include "txn.h"
#include "dbcore/sm-rep.h"
#include "dbcore/serial.h"

#include <atomic>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
#include <utility>

#if defined(SSN) || defined(SSI)
static __thread transaction::read_set_t *tls_read_set;
#endif

extern write_set_t tls_write_set[config::MAX_THREADS];

transaction::transaction(uint64_t flags, str_arena &sa)
    : flags(flags), sa(&sa), write_set(tls_write_set[thread::my_id()]) {
  if (config::is_backup_srv()) {
    // Read-only transaction on backup - grab a begin timestamp and go.
    // A read-only 'transaction' on a backup basically is reading a
    // consistent snapshot back in time. No CC involved.
    thread_local xid_context *ctx = nullptr;
    if (!ctx) {
      ctx = xid_get_context(xid_alloc());
    }
    xc = ctx;
    RCU::rcu_enter();
    xc->begin = std::min<uint64_t>(volatile_read(rep::replayed_lsn_offset),
                                   volatile_read(*rep::global_persisted_lsn_ptr));
    ASSERT(xc->begin);
  } else {
    initialize_read_write();
  }
}

void transaction::initialize_read_write() {
  if (config::phantom_prot) {
    absent_set.set_empty_key(NULL);  // google dense map
    absent_set.clear();
  }
  write_set.clear();
#if defined(SSN) || defined(SSI)
  if (unlikely(not tls_read_set)) {
    tls_read_set = new read_set_t;
    tls_read_set->reserve(2000);
  }
  read_set = tls_read_set;
  read_set->clear();
#endif
  xid = TXN::xid_alloc();
  xc = xid_get_context(xid);
  xc->begin_epoch = MM::epoch_enter();
#if defined(SSN) || defined(SSI)
  xc->xct = this;
{'fraction_non_alphanumeric': 0.143343653250774, 'fraction_numerical': 0.0043343653250774, 'mean_word_length': 4.262214983713355, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2900044', 'n_tokens_mistral': 1206, 'n_tokens_neox': 1183, 'n_words': 245}