コード例 #1
0
    def write_relation(self, relation: Relationship) -> Relationship:
        """
        Writes relation to file.
        :param relation: - relation written
        """
        if relation.next_prop is not None:
            relation.next_prop = self.write_property(relation.next_prop)

        if relation.id == cfg.INV_ID:
            relation.id = self._get_relation_id()
        relation.label = self.write_label(relation.label)

        if relation.first_node is not None:
            first_node = self.read_node(relation.first_node.id)
            if first_node.next_rel is None:
                first_node.next_rel = relation
                self.write_node(first_node)
            else:
                relation = self._update_next_rel(first_node, relation)

        if relation.second_node is not None:
            second_node = self.read_node(relation.second_node.id)
            if second_node.next_rel is None:
                second_node.next_rel = relation

                self.write_node(second_node)
            else:
                relation = self._update_next_rel(second_node, relation)

        value = Packer.pack_relation(relation)
        self._write_bytes(self.relations, relation.id * cfg.RELATION_SIZE,
                          value)
        return relation
コード例 #2
0
    def _swap_relation_pointer(self, next: Relationship, prev: Relationship):
        """
        Swaps pointer of two relations. Helper function for deletion of relation
        :param next:
        :param prev:
        :return:
        """
        if prev.second_node == next.second_node:
            prev.second_next_rel = next.id
            next.second_prev_rel = prev.id
        elif prev.first_node == next.first_node:
            prev.first_next_rel = next.id
            next.first_prev_rel = prev.id
        elif prev.first_node == next.second_node:
            prev.first_next_rel = next.id
            next.second_prev_rel = prev.id
        elif prev.second_node == next.first_node:
            prev.second_next_rel = next.id
            next.first_prev_rel = prev.id
        else:
            raise Exception('No same nodes to swap')

        second_prev_rel_packed = Packer.pack_relation(prev)
        second_next_rel_packed = Packer.pack_relation(next)
        self._write_bytes(self.relations, next.id * cfg.RELATION_SIZE,
                          second_next_rel_packed)
        self._write_bytes(self.relations, prev.id * cfg.RELATION_SIZE,
                          second_prev_rel_packed)
コード例 #3
0
 def _fix_prev_rel(self, current: Relationship, prev_rel: Relationship):
     """
     Sets prev_rel next pointer to INV_ID
     :param current:
     :param prev_rel:
     :return:
     """
     if (current.second_node == prev_rel.second_node):
         prev_rel.second_next_id = cfg.INV_ID
     elif (current.second_node == prev_rel.first_node):
         prev_rel.first_next_id = cfg.INV_ID
     prev_packed = Packer.pack_relation(prev_rel)
     self._write_bytes(self.relations, prev_rel.id * cfg.RELATION_SIZE,
                       prev_packed)
コード例 #4
0
 def _update_next_rel(self, node: Node, relation: Relationship):
     next_rel = self.read_relation(node.next_rel)
     node.next_rel = relation.id
     if next_rel.second_node.id == node.id:
         next_rel.second_prev_rel = relation.id
     if next_rel.first_node.id == node.id:
         next_rel.first_prev_rel = relation.id
     self.write_node(node)
     value = Packer.pack_relation(next_rel)
     self._write_bytes(self.relations, next_rel.id * cfg.RELATION_SIZE,
                       value)
     if relation.first_node.id == node.id:
         relation.first_next_rel = next_rel
     if relation.second_node.id == node.id:
         relation.second_next_rel = next_rel
     return relation
コード例 #5
0
 def test_del_relation(self):
     io = Io()
     value = "You spin my head right ground right ground"
     label = Label(cfg.INV_ID, value)
     label = io.write_label(label)
     prop_value = True
     property = Property(cfg.INV_ID, PropertyType.BOOL, label, prop_value,
                         None)
     property = io.write_property(property)
     node = Node(cfg.INV_ID, label, property, None)
     node2 = Node(cfg.INV_ID, label, property, None)
     written1 = io.write_node(node)
     written2 = io.write_node(node2)
     relation = Relationship(cfg.INV_ID, False, written1, written2, label,
                             property, None, None, None, None)
     written = io.write_relation(relation)
     io.del_relation(written.id)
     retrived = io.get_relations_by_id([written.id])
     node1 = io.read_node(written1.id)
     node2 = io.read_node(written2.id)
     self.assertEqual(len(retrived), 0)
     print(node1.next_rel)
     print(node2.next_rel)
     self.assertEqual(node1.next_rel is None, True)
     self.assertEqual(node2.next_rel is None, True)
コード例 #6
0
    def test_relation_io(self):
        io = Io()
        value = "You spin my head right ground right ground"
        label = Label(cfg.INV_ID, value)
        label = io.write_label(label)
        prop_value = True
        property = Property(cfg.INV_ID, PropertyType.BOOL, label, prop_value,
                            None)
        property = io.write_property(property)
        node = Node(cfg.INV_ID, label, property, None)
        node2 = Node(cfg.INV_ID, label, property, None)
        written1 = io.write_node(node)
        written2 = io.write_node(node2)
        relation = Relationship(cfg.INV_ID, False, written1, written2, label,
                                property, None, None, None, None)
        written = io.write_relation(relation)
        retrieved = io.read_relation(written.id)

        written1 = io.read_node(written1.id)
        written2 = io.read_node(written2.id)

        self.assertEqual(retrieved.label.value, value)
        self.assertEqual(retrieved.next_prop.value, prop_value)
        self.assertEqual(retrieved.first_node.id, written1.id)
        self.assertEqual(retrieved.second_node.id, written2.id)
        self.assertEqual(written2.next_rel, retrieved.id)
        self.assertEqual(written1.next_rel, retrieved.id)
コード例 #7
0
 def test_multirelation_deletion(self):
     io = Io()
     value = "You spin my head right ground right ground"
     label = Label(cfg.INV_ID, value)
     label = io.write_label(label)
     prop_value = True
     property = Property(cfg.INV_ID, PropertyType.BOOL, label, prop_value,
                         None)
     property = io.write_property(property)
     node = Node(cfg.INV_ID, label, property, None)
     node2 = Node(cfg.INV_ID, label, property, None)
     written_node1 = io.write_node(node)
     written_node2 = io.write_node(node2)
     relation1 = Relationship(cfg.INV_ID, False, written_node1,
                              written_node2, label, property, None, None,
                              None, None)
     relation2 = Relationship(cfg.INV_ID, False, written_node1,
                              written_node2, label, property, None, None,
                              None, None)
     written_rel1 = io.write_relation(relation1)
     written_rel2 = io.write_relation(relation2)
     io.del_node(written_node1.id)
     retrived = io.get_relations_by_id([written_rel1.id, written_rel2.id])
     self.assertEqual(len(retrived), 0)
コード例 #8
0
    def read_relation(self, id) -> Relationship or None:
        """
        Reads single relation by it's id
        :param id: offset of relation to read
        :return: Relation unpacked
        """
        if id > self.last_relation_id:
            raise Exception('Relation ID is out of range')

        relation_bytes = self._read_bytes(self.relations, id,
                                          cfg.RELATION_SIZE)
        in_use, type, first_node, second_node, label, property, first_prev_relation, first_next_relation, \
        second_prev_relation, second_next_relation = Unpacker.unpack_relation(relation_bytes)
        if in_use:
            label = self.read_label(label)
            if property != cfg.INV_ID:
                property = self.read_property(property)
            else:
                property = None

            if first_node != cfg.INV_ID:
                first_node = self.read_node(first_node)
            else:
                first_node = None
            if second_node != cfg.INV_ID:
                second_node = self.read_node(second_node)
            else:
                second_node = None
            if first_next_relation == cfg.INV_ID:
                first_next_relation = None
            if second_next_relation == cfg.INV_ID:
                second_next_relation = None
            if first_prev_relation == cfg.INV_ID:
                first_prev_relation = None
            if second_prev_relation == cfg.INV_ID:
                second_prev_relation = None
            return Relationship(id, type, first_node, second_node, label,
                                property, first_prev_relation,
                                first_next_relation, second_prev_relation,
                                second_next_relation)
        else:
            return None
コード例 #9
0
ファイル: graph_engine.py プロジェクト: goshaQ/lime
    def create_relationship(self, first_node, second_node, relationship):
        """
        Creates new relationships between nodes that match 'first_node' and 'second_node'.
        
        :param first_node: A pair (<label>, <properties>) corresponding to the node at the start of a relationship.
        :param second_node: A pair (<label>, <properties>) corresponding to the node at the end of a relationship.
        :param relationship: A triplet (<label>, <properties>, <direction>) corresponding to a relationship.
        :return: Void
        """
        label, next_prop, direction = relationship

        label = self._dedupe_label(label)
        next_prop = self._dedupe_next_prop(next_prop)

        is_directed = False
        if direction == 1:
            is_directed = True
        elif direction == -1:
            is_directed = True
            first_node, second_node = second_node, first_node

        retrieved_first_node = self._retrieve_node(first_node)
        retrieved_second_node = self._retrieve_node(second_node)

        for first in retrieved_first_node:
            for second in retrieved_second_node:
                created_relationship = self._io.write_relation(
                    Relationship(cfg.INV_ID, is_directed, first, second, label,
                                 next_prop, None, None, None, None))
                label, next_prop = created_relationship.label, created_relationship.next_prop

                # Add new labels to the corresponding cache
                self._lb_cache[label.value] = label
                while next_prop is not None:
                    self._lb_cache[next_prop.label] = next_prop.label
                    next_prop = next_prop.next_prop