Ejemplo n.º 1
0
bool ConcurrentTableSharedStore::exists(CStrRef key) {
  const StoreValue *sval;
  ConditionalReadLock l(m_lock, !RuntimeOption::ApcConcurrentTableLockFree ||
                                m_lockingFlag);
  bool expired = false;
  {
    Map::const_accessor acc;
    if (!m_vars.find(acc, key.data())) {
      log_apc(std_apc_miss);
      return false;
    } else {
      sval = &acc->second;
      if (sval->expired()) {
        // Because it only has a read lock on the data, deletion from
        // expiration has to happen after the lock is released
        expired = true;
      } else {
        // No need toLocal() here, avoiding the copy
        if (sval->inMem()) {
          stats_on_get(key.get(), sval->var);
        }
      }
    }
  }
  if (expired) {
    log_apc(std_apc_miss);
    eraseImpl(key, true);
    return false;
  }
  log_apc(std_apc_hit);
  return true;
}
Ejemplo n.º 2
0
bool ConcurrentTableSharedStore::get(const String& key, Variant &value) {
  const StoreValue *sval;
  APCHandle *svar = nullptr;
  ConditionalReadLock l(m_lock, !apcExtension::ConcurrentTableLockFree ||
                                m_lockingFlag);
  bool expired = false;
  bool promoteObj = false;
  {
    Map::const_accessor acc;
    if (!m_vars.find(acc, tagStringData(key.get()))) {
      log_apc(std_apc_miss);
      return false;
    } else {
      sval = &acc->second;
      if (sval->expired()) {
        // Because it only has a read lock on the data, deletion from
        // expiration has to happen after the lock is released
        expired = true;
      } else {
        if (!sval->inMem()) {
          std::lock_guard<SmallLock> sval_lock(sval->lock);

          if (!sval->inMem()) {
            svar = unserialize(key, sval);
            if (!svar) return false;
          } else {
            svar = sval->var;
          }
        } else {
          svar = sval->var;
        }

        if (apcExtension::AllowObj && svar->is(KindOfObject) &&
            !svar->getObjAttempted()) {
          // Hold ref here for later promoting the object
          svar->incRef();
          promoteObj = true;
        }
        value = svar->toLocal();
        stats_on_get(key.get(), svar);
      }
    }
  }
  if (expired) {
    log_apc(std_apc_miss);
    eraseImpl(key, true);
    return false;
  }
  log_apc(std_apc_hit);

  if (promoteObj)  {
    handlePromoteObj(key, svar, value);
    // release the extra ref
    svar->decRef();
  }
  return true;
}
Ejemplo n.º 3
0
bool ConcurrentTableSharedStore::cas(CStrRef key, int64 old, int64 val) {
  bool success = false;
  ConditionalReadLock l(m_lock, !RuntimeOption::ApcConcurrentTableLockFree ||
                                m_lockingFlag);
  StoreValue *sval;
  {
    Map::accessor acc;
    if (m_vars.find(acc, key.data())) {
      sval = &acc->second;
      if (!sval->expired() && get_int64_value(sval) == old) {
        SharedVariant *var = construct(Variant(val));
        sval->var->decRef();
        sval->var = var;
        success = true;
        log_apc(std_apc_cas);
      }
    }
  }
  return success;
}
Ejemplo n.º 4
0
bool ConcurrentTableSharedStore::cas(const String& key, int64_t old,
                                     int64_t val) {
  bool success = false;
  ConditionalReadLock l(m_lock, !apcExtension::ConcurrentTableLockFree ||
                                m_lockingFlag);
  StoreValue *sval;
  {
    Map::accessor acc;
    if (m_vars.find(acc, tagStringData(key.get()))) {
      sval = &acc->second;
      if (!sval->expired() && get_int64_value(sval) == old) {
        APCHandle *var = construct(Variant(val));
        sval->var->decRef();
        sval->var = var;
        success = true;
        log_apc(std_apc_cas);
      }
    }
  }
  return success;
}
Ejemplo n.º 5
0
int64 ConcurrentTableSharedStore::inc(CStrRef key, int64 step, bool &found) {
  found = false;
  int64 ret = 0;
  ConditionalReadLock l(m_lock, !RuntimeOption::ApcConcurrentTableLockFree ||
                                m_lockingFlag);
  StoreValue *sval;
  {
    Map::accessor acc;
    if (m_vars.find(acc, key.data())) {
      sval = &acc->second;
      if (!sval->expired()) {
        ret = get_int64_value(sval) + step;
        SharedVariant *svar = construct(Variant(ret));
        sval->var->decRef();
        sval->var = svar;
        found = true;
        log_apc(std_apc_hit);
      }
    }
  }
  return ret;
}
Ejemplo n.º 6
0
int64_t ConcurrentTableSharedStore::inc(const String& key, int64_t step,
                                        bool &found) {
  found = false;
  int64_t ret = 0;
  ConditionalReadLock l(m_lock, !apcExtension::ConcurrentTableLockFree ||
                                m_lockingFlag);
  StoreValue *sval;
  {
    Map::accessor acc;
    if (m_vars.find(acc, tagStringData(key.get()))) {
      sval = &acc->second;
      if (!sval->expired()) {
        ret = get_int64_value(sval) + step;
        APCHandle *svar = construct(Variant(ret));
        sval->var->decRef();
        sval->var = svar;
        found = true;
        log_apc(std_apc_hit);
      }
    }
  }
  return ret;
}
Ejemplo n.º 7
0
bool ConcurrentTableSharedStore::store(CStrRef key, CVarRef value, int64 ttl,
                                       bool overwrite /* = true */) {
  StoreValue *sval;
  SharedVariant* svar = construct(value);
  ConditionalReadLock l(m_lock, !RuntimeOption::ApcConcurrentTableLockFree ||
                                m_lockingFlag);
  const char *kcp = strdup(key.data());
  bool present;
  time_t expiry = 0;
  bool overwritePrime = false;
  {
    Map::accessor acc;
    present = !m_vars.insert(acc, kcp);
    sval = &acc->second;
    bool update = false;
    if (present) {
      free((void *)kcp);
      if (overwrite || sval->expired()) {
        // if ApcTTLLimit is set, then only primed keys can have expiry == 0
        overwritePrime = (sval->expiry == 0);
        if (sval->inMem()) {
          stats_on_update(key.get(), sval, svar,
                          adjust_ttl(ttl, overwritePrime));
          sval->var->decRef();
          update = true;
        } else {
          // mark the inFile copy invalid since we are updating the key
          sval->sAddr = NULL;
          sval->sSize = 0;
        }
      } else {
        svar->decRef();
        return false;
      }
    }
    int64 adjustedTtl = adjust_ttl(ttl, overwritePrime);
    if (check_noTTL(key.data())) {
      adjustedTtl = 0;
    }
    sval->set(svar, adjustedTtl);
    expiry = sval->expiry;
    if (!update) {
      stats_on_add(key.get(), sval, adjustedTtl, false, false);
    }
  }
  if (expiry) {
    addToExpirationQueue(key.data(), expiry);
  }
  if (RuntimeOption::ApcExpireOnSets) {
    purgeExpired();
  }
  if (present) {
    log_apc(std_apc_update);
  } else {
    log_apc(std_apc_new);
    if (RuntimeOption::EnableStats && RuntimeOption::EnableAPCKeyStats) {
      string prefix = "apc.new." + GetSkeleton(key);
      ServerStats::Log(prefix, 1);
    }
  }
  return true;
}