Ejemplo n.º 1
0
 def applyFormula(self, formula):
     names = {item[1].name for item in self.reorder}
     condition = formula.getFormulaOf(names)
     self.condition = condition if condition else TrueFormula()
     if not self.isLeaf():
         self.left.applyFormula(self.condition)
         self.right.applyFormula(self.condition)
Ejemplo n.º 2
0
 def __init__(self,
              isSeq,
              slidingWindow,
              reorder: List[Tuple[int, QItem]] = None,
              parent=None,
              left=None,
              right=None):
     self.reorder = reorder
     self.parent = parent
     self.left = left
     self.right = right
     self.partialMatches = []
     self.slidingWindow = slidingWindow
     self.condition = TrueFormula()
     self.isSeq = isSeq
     self.unhandledPartialMatches = Queue()
Ejemplo n.º 3
0
def nonFrequencyPatternSearch4Test(createTestFile=False):
    pattern = Pattern(
        SeqOperator([
            QItem("AAPL", "a"),
            QItem("AMZN", "b"),
            QItem("AVID", "c"),
            QItem("LOCM", "d")
        ]), TrueFormula(), timedelta(minutes=7))
    runTest("nonFrequency4", [pattern], createTestFile)
Ejemplo n.º 4
0
def nonFrequencyPatternSearch5Test(createTestFile=False):
    pattern = Pattern(
        SeqOperator([
            QItem("AAPL", "a1"),
            QItem("LOCM", "b1"),
            QItem("AAPL", "a2"),
            QItem("LOCM", "b2"),
            QItem("AAPL", "a3"),
            QItem("LOCM", "b3")
        ]), TrueFormula(), timedelta(minutes=7))
    runTest("nonFrequency5", [pattern], createTestFile)
Ejemplo n.º 5
0
def frequencyPatternSearch3Test(createTestFile=False):
    pattern = Pattern(
        SeqOperator([
            QItem("AAPL", "a"),
            QItem("AAPL", "b"),
            QItem("AAPL", "c"),
            QItem("LOCM", "d")
        ]), TrueFormula(), timedelta(minutes=5))
    pattern.setAdditionalStatistics(StatisticsTypes.FREQUENCY_DICT, {
        "AAPL": 460,
        "LOCM": 219
    })
    runTest("frequency3", [pattern], createTestFile,
            AscendingFrequencyAlgorithm())
Ejemplo n.º 6
0
def frequencyPatternSearch5Test(createTestFile=False):
    pattern = Pattern(
        SeqOperator([
            QItem("AAPL", "a1"),
            QItem("LOCM", "b1"),
            QItem("AAPL", "a2"),
            QItem("LOCM", "b2"),
            QItem("AAPL", "a3"),
            QItem("LOCM", "b3")
        ]), TrueFormula(), timedelta(minutes=7))
    pattern.setAdditionalStatistics(StatisticsTypes.FREQUENCY_DICT, {
        "LOCM": 1,
        "AAPL": 2
    })  # {"AAPL": 460, "LOCM": 219}
    runTest("frequency5", [pattern], createTestFile,
            AscendingFrequencyAlgorithm())
Ejemplo n.º 7
0
class Node:
    def __init__(self,
                 isSeq,
                 slidingWindow,
                 reorder: List[Tuple[int, QItem]] = None,
                 parent=None,
                 left=None,
                 right=None):
        self.reorder = reorder
        self.parent = parent
        self.left = left
        self.right = right
        self.partialMatches = []
        self.slidingWindow = slidingWindow
        self.condition = TrueFormula()
        self.isSeq = isSeq
        self.unhandledPartialMatches = Queue()

    # Used in the root node.
    def consumeFirstPartialMatch(self):
        ret = self.partialMatches[0]
        del self.partialMatches[0]
        return ret

    def hasPartialMatches(self):
        return bool(
            self.partialMatches
        )  # if partial matches container is empty, evaluates to false.

    def getLastUnhandledPartialMatch(self):
        return self.unhandledPartialMatches.get()

    def getLeaves(self):
        if self.isLeaf():
            return [self]

        return self.left.getLeaves() + self.right.getLeaves()

    def applyFormula(self, formula):
        names = {item[1].name for item in self.reorder}
        condition = formula.getFormulaOf(names)
        self.condition = condition if condition else TrueFormula()
        if not self.isLeaf():
            self.left.applyFormula(self.condition)
            self.right.applyFormula(self.condition)

    def isLeaf(self):
        return self.left == self.right == None

    # Used only in leaves. Returns the event type, which is stored in the first (and only) qitem in the reorder.
    def getEventType(self):
        if not self.isLeaf():
            raise Exception()

        return self.reorder[0][1].eventType

    def setSubtrees(self, left, right):
        self.left = left
        self.right = right
        self.reorder = merge(self.left.reorder,
                             self.right.reorder,
                             key=lambda x: x[0])

    def setParent(self, parent):
        self.parent = parent

    @staticmethod
    def constructTree(isSeq, tree, args, slidingWindow, parent=None):
        if type(tree) == int:
            return Node(isSeq, slidingWindow, [(tree, args[tree])], parent)

        current = Node(isSeq, slidingWindow)
        leftTree, rightTree = tree
        left = Node.constructTree(isSeq, leftTree, args, slidingWindow,
                                  current)
        right = Node.constructTree(isSeq, rightTree, args, slidingWindow,
                                   current)
        current.setSubtrees(left, right)
        current.setParent(parent)

        return current

    def isLeftSubtree(self):
        if self.parent == None:
            raise Exception()

        return (self.parent.left is self)

    # Insert an event to a leaf.
    def handleEvent(self, event: Event):
        if not self.isLeaf():
            raise Exception()

        self.updatePartialMatchesToDate(event.date)

        # get event's qitem and make a binding to evaluate formula for the new event.
        qitem = self.reorder[0][1]
        binding = {qitem.name: event.event}

        if self.condition.eval(binding):
            self.addPartialMatch(PartialMatch([event]))
            if self.parent != None:
                self.parent.handleNewPartialMatch(self.isLeftSubtree())

    def updatePartialMatchesToDate(self, lastDate):
        if self.slidingWindow == timedelta.max:
            return
        count = binarySearchDateThreshold(self.partialMatches,
                                          lastDate - self.slidingWindow)
        self.partialMatches = self.partialMatches[count:]

    def addPartialMatch(self, pm: PartialMatch):
        index = binarySearchDateThreshold(self.partialMatches,
                                          pm.getFirstDate())
        self.partialMatches.insert(index, pm)
        self.unhandledPartialMatches.put(pm)

    # Internal node's update for a new partial match in one of the subtrees.
    def handleNewPartialMatch(self, originatorIsLeftSubtree):
        if self.isLeaf():
            raise Exception()

        if originatorIsLeftSubtree:
            newPartialMatch = self.left.getLastUnhandledPartialMatch()
            firstReorder = self.left.reorder
            self.right.updatePartialMatchesToDate(
                newPartialMatch.getLastDate())
            toCompare = self.right.partialMatches
            secondReorder = self.right.reorder
        else:
            newPartialMatch = self.right.getLastUnhandledPartialMatch()
            firstReorder = self.right.reorder
            self.left.updatePartialMatchesToDate(newPartialMatch.getLastDate())
            toCompare = self.left.partialMatches
            secondReorder = self.left.reorder

        self.updatePartialMatchesToDate(newPartialMatch.getLastDate())

        # given a partial match from one subtree, for each partial match
        # in the other subtree we check for new partial matches in this node.
        for partialMatch in toCompare:
            if self.slidingWindow != timedelta.max and \
                (partialMatch.getLastDate() - newPartialMatch.getFirstDate() > self.slidingWindow \
            or newPartialMatch.getLastDate() - partialMatch.getFirstDate() > self.slidingWindow):
                continue
            speculativePM = mergeAccordingTo(firstReorder,
                                             secondReorder,
                                             newPartialMatch.getPartialMatch(),
                                             partialMatch.getPartialMatch(),
                                             key=lambda x: x[0])
            if self.isSeq and not isSorted(speculativePM,
                                           key=lambda x: x.date):
                continue

            binding = {
                self.reorder[i][1].name: speculativePM[i].event
                for i in range(len(self.reorder))
            }
            if self.condition.eval(binding):
                self.addPartialMatch(PartialMatch(speculativePM))
                if self.parent:
                    self.parent.handleNewPartialMatch(self.isLeftSubtree())
        return