コード例 #1
0
ファイル: Detector.cpp プロジェクト: esterl/kdet-omnetpp
void Detector::handleMessage(cMessage *msg) {
    if (msg->arrivedOn("clock")) {
        // Schedule evaluation just a bit later, so that we have all sketches
        scheduleAt(
                simTime() + simtime_t(getParentModule()->par("interval")) * .8,
                msg);
    } else if (msg->isSelfMessage()) {
        evaluateCores();
        delete msg;
        clearReports();
    } else if (msg->arrivedOn("graphServerIn")) {
        updateCores(check_and_cast<CoresUpdate*>(msg));
    } else if (msg->arrivedOn("reportsIn")) {
        updateReports(check_and_cast<Report*>(msg));
    } else {
        delete msg;
    }
}
コード例 #2
0
ファイル: ng_extparam.cpp プロジェクト: 01org/hyperscan
void handleExtendedParams(ReportManager &rm, NGWrapper &g,
                          UNUSED const CompileContext &cc) {
    if (!hasExtParams(g)) {
        return;
    }

    depth minWidth = findMinWidth(g);
    depth maxWidth = findMaxWidth(g);
    bool is_anchored = !has_proper_successor(g.startDs, g)
                     && out_degree(g.start, g);
    bool has_offset_adj = hasOffsetAdjustments(rm, g);

    DEBUG_PRINTF("minWidth=%s, maxWidth=%s, anchored=%d, offset_adj=%d\n",
                 minWidth.str().c_str(), maxWidth.str().c_str(), is_anchored,
                 has_offset_adj);

    DepthMinMax match_depths = findMatchLengths(rm, g);
    DEBUG_PRINTF("match depths %s\n", match_depths.str().c_str());

    if (is_anchored && maxWidth.is_finite() && g.min_offset > maxWidth) {
        ostringstream oss;
        oss << "Expression is anchored and cannot satisfy min_offset="
            << g.min_offset << " as it can only produce matches of length "
            << maxWidth << " bytes at most.";
        throw CompileError(g.expressionIndex, oss.str());
    }

    if (minWidth > g.max_offset) {
        ostringstream oss;
        oss << "Expression has max_offset=" << g.max_offset << " but requires "
             << minWidth << " bytes to match.";
        throw CompileError(g.expressionIndex, oss.str());
    }

    if (maxWidth.is_finite() && match_depths.max < g.min_length) {
        ostringstream oss;
        oss << "Expression has min_length=" << g.min_length << " but can "
            "only produce matches of length " << match_depths.max <<
            " bytes at most.";
        throw CompileError(g.expressionIndex, oss.str());
    }

    if (g.min_length && g.min_length <= match_depths.min) {
        DEBUG_PRINTF("min_length=%llu constraint is unnecessary\n",
                     g.min_length);
        g.min_length = 0;
    }

    if (!hasExtParams(g)) {
        return;
    }

    pruneVacuousEdges(g);
    pruneUnmatchable(g, rm);

    if (!has_offset_adj) {
        pruneExtUnreachable(g);
    }

    // We may have removed all the edges to accept, in which case this
    // expression cannot match.
    if (in_degree(g.accept, g) == 0 && in_degree(g.acceptEod, g) == 1) {
        throw CompileError(g.expressionIndex, "Extended parameter "
                "constraints can not be satisfied for any match from "
                "this expression.");
    }

    // Remove reports on vertices without an edge to accept (which have been
    // pruned above).
    clearReports(g);

    // Recalc.
    minWidth = findMinWidth(g);
    maxWidth = findMaxWidth(g);
    is_anchored = proper_out_degree(g.startDs, g) == 0 &&
                  out_degree(g.start, g);
    has_offset_adj = hasOffsetAdjustments(rm, g);

    // If the pattern is completely anchored and has a min_length set, this can
    // be converted to a min_offset.
    if (g.min_length && (g.min_offset <= g.min_length) && is_anchored) {
        DEBUG_PRINTF("converting min_length to min_offset=%llu for "
                     "anchored case\n", g.min_length);
        g.min_offset = g.min_length;
        g.min_length = 0;
    }

    if (g.min_offset && g.min_offset <= minWidth && !has_offset_adj) {
        DEBUG_PRINTF("min_offset=%llu constraint is unnecessary\n",
                     g.min_offset);
        g.min_offset = 0;
    }

    if (!hasExtParams(g)) {
        return;
    }

    // If the pattern has a min_length and is of "ratchet" form with one
    // unbounded repeat, that repeat can become a bounded repeat.
    // e.g. /foo.*bar/{min_length=100} --> /foo.{94,}bar/
    if (g.min_length && transformMinLengthToRepeat(rm, g)) {
        DEBUG_PRINTF("converted min_length to bounded repeat\n");
        // recalc
        minWidth = findMinWidth(g);
    }

    // If the pattern is unanchored, has a max_offset and has not asked for
    // SOM, we can use that knowledge to anchor it which will limit its
    // lifespan. Note that we can't use this transformation if there's a
    // min_length, as it's currently handled using "sly SOM".

    // Note that it is possible to handle graphs that have a combination of
    // anchored and unanchored paths, but it's too tricky for the moment.

    if (g.max_offset != MAX_OFFSET && !g.som && !g.min_length &&
                !has_offset_adj && isUnanchored(g)) {
        if (anchorPatternWithBoundedRepeat(g, minWidth, maxWidth)) {
            DEBUG_PRINTF("minWidth=%s, maxWidth=%s\n", minWidth.str().c_str(),
                         maxWidth.str().c_str());
            if (minWidth == maxWidth) {
                // For a fixed width pattern, we can retire the offsets as they
                // are implicit in the graph now.
                g.min_offset = 0;
                g.max_offset = MAX_OFFSET;
            }
        }
    }
    //dumpGraph("final.dot", g.g);

    if (!hasExtParams(g)) {
        return;
    }

    set<NFAVertex> done;
    updateReportBounds(rm, g, g.accept, done);
    updateReportBounds(rm, g, g.acceptEod, done);
}
コード例 #3
0
ファイル: ng_extparam.cpp プロジェクト: 01org/hyperscan
/** If the pattern has a min_length and is of "ratchet" form with one unbounded
 * repeat, that repeat can become a bounded repeat.
 *
 *     /foo.*bar/{min_length=100} --> /foo.{94,}bar/
 */
static
bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
    assert(g.min_length);

    if (g.min_length > MAX_MINLENGTH_TO_CONVERT) {
        return false;
    }

    // If the pattern has virtual starts, we probably don't want to touch it.
    if (hasVirtualStarts(g)) {
        DEBUG_PRINTF("virtual starts, bailing\n");
        return false;
    }

    // The graph must contain a single cyclic vertex (other than startDs), and
    // that vertex can have one pred and one successor.
    NFAVertex cyclic = findSingleCyclic(g);
    if (cyclic == NGHolder::null_vertex()) {
        return false;
    }

    NGHolder::adjacency_iterator ai, ae;
    tie(ai, ae) = adjacent_vertices(g.start, g);
    if (*ai == g.startDs) {
        ++ai;
    }
    NFAVertex v = *ai;
    if (++ai != ae) {
        DEBUG_PRINTF("more than one initial vertex\n");
        return false;
    }

    u32 width = 0;


    // Walk from the start vertex to the cyclic state and ensure we have a
    // chain of vertices.
    while (v != cyclic) {
        DEBUG_PRINTF("vertex %u\n", g[v].index);
        width++;
        tie(ai, ae) = adjacent_vertices(v, g);
        set<NFAVertex> succ(ai, ae);
        if (contains(succ, cyclic)) {
            if (succ.size() == 1) {
                v = cyclic;
            } else if (succ.size() == 2) {
                // Cyclic and jump edge.
                succ.erase(cyclic);
                NFAVertex v2 = *succ.begin();
                if (!edge(cyclic, v2, g).second) {
                    DEBUG_PRINTF("bad form\n");
                    return false;
                }
                v = cyclic;
            } else {
                DEBUG_PRINTF("bad form\n");
                return false;
            }
        } else {
            if (succ.size() != 1) {
                DEBUG_PRINTF("bad form\n");
                return false;
            }
            v = *succ.begin();
        }
    }

    // Check the cyclic state is A-OK.
    v = getSoleDestVertex(g, cyclic);
    if (v == NGHolder::null_vertex()) {
        DEBUG_PRINTF("cyclic has more than one successor\n");
        return false;
    }

    // Walk from the cyclic state to an accept and ensure we have a chain of
    // vertices.
    while (!is_any_accept(v, g)) {
        DEBUG_PRINTF("vertex %u\n", g[v].index);
        width++;
        tie(ai, ae) = adjacent_vertices(v, g);
        set<NFAVertex> succ(ai, ae);
        if (succ.size() != 1) {
            DEBUG_PRINTF("bad form\n");
            return false;
        }
        v = *succ.begin();
    }

    int offsetAdjust = 0;
    if (!hasOffsetAdjust(rm, g, &offsetAdjust)) {
        return false;
    }
    DEBUG_PRINTF("adjusting width by %d\n", offsetAdjust);
    width += offsetAdjust;

    DEBUG_PRINTF("width=%u, vertex %u is cyclic\n", width,
                  g[cyclic].index);

    if (width >= g.min_length) {
        DEBUG_PRINTF("min_length=%llu is guaranteed, as width=%u\n",
                      g.min_length, width);
        g.min_length = 0;
        return true;
    }

    vector<NFAVertex> preds;
    vector<NFAEdge> dead;
    for (auto u : inv_adjacent_vertices_range(cyclic, g)) {
        DEBUG_PRINTF("pred %u\n", g[u].index);
        if (u == cyclic) {
            continue;
        }
        preds.push_back(u);

        // We want to delete the out-edges of each predecessor, but need to
        // make sure we don't delete the startDs self loop.
        for (const auto &e : out_edges_range(u, g)) {
            if (target(e, g) != g.startDs) {
                dead.push_back(e);
            }
        }
    }

    remove_edges(dead, g);

    assert(!preds.empty());

    const CharReach &cr = g[cyclic].char_reach;

    for (u32 i = 0; i < g.min_length - width - 1; ++i) {
        v = add_vertex(g);
        g[v].char_reach = cr;

        for (auto u : preds) {
            add_edge(u, v, g);
        }
        preds.clear();
        preds.push_back(v);
    }
    assert(!preds.empty());
    for (auto u : preds) {
        add_edge(u, cyclic, g);
    }

    g.renumberVertices();
    g.renumberEdges();
    clearReports(g);

    g.min_length = 0;
    return true;
}
コード例 #4
0
ファイル: Detector.cpp プロジェクト: esterl/kdet-omnetpp
void Detector::finish() {
    clearReports();
}