1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright (C) 2022-2024 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Kea Hooks Basic
// Commercial End User License Agreement v2.0. See COPYING file in the premium/
// directory.

#include <config.h>

#include <expression_cache.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <eval/token.h>
#include <eval/eval_context.h>
#include <util/multi_threading_mgr.h>

using namespace isc;
using namespace isc::dhcp;
using namespace isc::eval;
using namespace std;

namespace isc {
namespace ddns_tuning {

bool
ExpressionCache::findExpression(const SubnetID& subnet_id, ExpressionPtr& expression) {
    if (util::MultiThreadingMgr::instance().getMode()) {
        std::lock_guard<std::mutex> lk(mutex_);
        return (findExpressionInternal(subnet_id, expression));
    } else {
        return (findExpressionInternal(subnet_id, expression));
    }
}

bool
ExpressionCache::findExpressionInternal(const SubnetID& subnet_id, ExpressionPtr& expression) const {
    auto it = expressions_.find(subnet_id);
    if (it != expressions_.end()) {
        expression = it->second;
        return (true);
    }

    expression = ExpressionPtr();
    return (false);
}

ExpressionPtr
ExpressionCache::parseAndCacheExpression(const SubnetID& subnet_id, const string& expression_str,
                                 uint32_t family) {
    ExpressionPtr expression;
    try {
        // We allow empty expressions so higher precedence scopes may
        // override lower precedence scopes.
        if (expression_str.empty()) {
            expression.reset(new Expression());
        } else {
            EvalContext eval_ctx(family == AF_INET ? Option::V4 : Option::V6);
            eval_ctx.parseString(expression_str, EvalContext::PARSER_STRING);
            expression.reset(new Expression(eval_ctx.expression));
        }
    } catch (const std::exception& ex) {
        isc_throw(BadValue, "error parsing expression: ["
                  << expression_str << "] : " << ex.what());
    }

    cacheExpression(subnet_id, expression);
    return (expression);
}

void
ExpressionCache::cacheExpression(const SubnetID& subnet_id, ExpressionPtr& expression) {
    if (util::MultiThreadingMgr::instance().getMode()) {
        std::lock_guard<std::mutex> lk(mutex_);
        expressions_[subnet_id] = expression;
    } else {
        expressions_[subnet_id] = expression;
    }
}

void
ExpressionCache::clear() {
    if (util::MultiThreadingMgr::instance().getMode()) {
        std::lock_guard<std::mutex> lk(mutex_);
        // Discard the contents.
        expressions_.clear();

        // We use modification time to remember the last time we flushed.
        updateModificationTime();
    } else {
        // Discard the contents.
        expressions_.clear();

        // We use modification time to remember the last time we flushed.
        updateModificationTime();
    }
}

size_t
ExpressionCache::size() {
    if (util::MultiThreadingMgr::instance().getMode()) {
        std::lock_guard<std::mutex> lk(mutex_);
        return (expressions_.size());
    } else {
        return (expressions_.size());
    }
}

boost::posix_time::ptime
ExpressionCache::getLastFlushTime() {
    if (util::MultiThreadingMgr::instance().getMode()) {
        std::lock_guard<std::mutex> lk(mutex_);
        return (BaseStampedElement::getModificationTime());
    } else {
        return (BaseStampedElement::getModificationTime());
    }
}

} // end of namespace ddns_tuning
} // end of namespace isc