summaryrefslogtreecommitdiff
path: root/archaeological_context_records
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2021-06-17 18:31:26 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2021-06-17 18:31:26 +0200
commitf5680038fdd0bb230c160fd4df3d2c1deab07faf (patch)
tree3e63695736a8981a9c8b4391b671765f5deef6d4 /archaeological_context_records
parent323006e473ee3077cd91f9011090a4df1de5c0ae (diff)
downloadIshtar-f5680038fdd0bb230c160fd4df3d2c1deab07faf.tar.bz2
Ishtar-f5680038fdd0bb230c160fd4df3d2c1deab07faf.zip
Context records: Optimize record relations - fix equals
Diffstat (limited to 'archaeological_context_records')
-rw-r--r--archaeological_context_records/models.py42
-rw-r--r--archaeological_context_records/tests.py97
2 files changed, 76 insertions, 63 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py
index 65145be98..454e83e8a 100644
--- a/archaeological_context_records/models.py
+++ b/archaeological_context_records/models.py
@@ -1454,14 +1454,23 @@ class ContextRecordTree(RelationsViews):
return new_trees
@classmethod
- def _get_equals(cls, item_id, equal_rel_types):
- equals = list(RecordRelations.objects.values_list(
+ def _get_equals(cls, item_id, equal_rel_types, exclude=None):
+ if not exclude:
+ exclude = [item_id]
+ q = RecordRelations.objects.values_list(
"right_record_id", flat=True).filter(
- left_record_id=item_id, relation_type_id__in=equal_rel_types))
- equals += list(RecordRelations.objects.values_list(
+ left_record_id=item_id, relation_type_id__in=equal_rel_types)
+ q = q.exclude(right_record_id__in=exclude)
+ equals = list(q)
+ q = RecordRelations.objects.values_list(
"left_record_id", flat=True).filter(
- right_record_id=item_id, relation_type_id__in=equal_rel_types))
- return set(equals)
+ right_record_id=item_id, relation_type_id__in=equal_rel_types)
+ q = q.exclude(left_record_id__in=exclude)
+ equals += list(q)
+ exclude += equals
+ for eq_id in equals:
+ equals += cls._get_equals(eq_id, equal_rel_types, exclude=exclude)
+ return equals
@classmethod
def _update_equals(cls, item_id, equals):
@@ -1485,24 +1494,32 @@ class ContextRecordTree(RelationsViews):
equal_rel_types = cls._get_base_equal_relations()
keys = []
for child_id, parent_id in relations:
- equals = set(cls._get_equals(child_id, equal_rel_types))
- keys += cls._update_equals(child_id, equals)
- for alt_child in equals:
+ equals_child = set(cls._get_equals(child_id, equal_rel_types))
+ keys += cls._update_equals(child_id, equals_child)
+ for alt_child in equals_child:
if alt_child != child_id:
cls.objects.get_or_create(
key=f"{alt_child}_{parent_id}",
cr_id=alt_child, cr_parent_id=parent_id
)
keys.append((alt_child, parent_id))
- equals = set(cls._get_equals(parent_id, equal_rel_types))
- keys += cls._update_equals(parent_id, equals)
- for alt_parent in equals:
+ equals_parent = set(cls._get_equals(parent_id, equal_rel_types))
+ keys += cls._update_equals(parent_id, equals_parent)
+ for alt_parent in equals_parent:
if alt_parent != parent_id:
cls.objects.get_or_create(
key=f"{child_id}_{alt_parent}",
cr_id=child_id, cr_parent_id=alt_parent
)
keys.append((child_id, alt_parent))
+
+ for alt_child in equals_child:
+ if alt_child != child_id:
+ cls.objects.get_or_create(
+ key=f"{alt_child}_{alt_parent}",
+ cr_id=alt_child, cr_parent_id=alt_parent
+ )
+ keys.append((alt_child, alt_parent))
return set(keys)
@classmethod
@@ -1541,7 +1558,6 @@ class ContextRecordTree(RelationsViews):
equals = set(cls._get_equals(item_id, equal_rel_types))
all_relations.update(cls._update_equals(item_id, equals))
-
## delete old relations
if not already_updated:
already_updated = [item_id]
diff --git a/archaeological_context_records/tests.py b/archaeological_context_records/tests.py
index 553731542..6b3e9f648 100644
--- a/archaeological_context_records/tests.py
+++ b/archaeological_context_records/tests.py
@@ -884,7 +884,7 @@ class RecordRelationsTest(ContextRecordInit, TestCase):
model = models.ContextRecord
def setUp(self):
- for idx in range(1, 11):
+ for idx in range(1, 15):
self.create_context_record({"label": f"CR {idx}"})
def test_relations(self):
@@ -949,6 +949,7 @@ class RecordRelationsTest(ContextRecordInit, TestCase):
profile = get_current_profile(force=True)
models.ContextRecordTree.check_engine()
crs = self.context_records
+
rel_type_1 = models.RelationType.objects.create(
symmetrical=False, txt_idx="rel_1",
logical_relation='included'
@@ -978,6 +979,19 @@ class RecordRelationsTest(ContextRecordInit, TestCase):
right_record=crs[parent_idx - 1],
relation_type=rel_type_1
)
+ rel_type_2 = models.RelationType.objects.create(
+ symmetrical=True, txt_idx="rel_2",
+ logical_relation='equal'
+ )
+ equal_relations = (
+ (10, 11), (11, 12), (5, 13), (3, 14)
+ )
+ for child_idx, parent_idx in equal_relations:
+ models.RecordRelations.objects.create(
+ left_record=crs[child_idx - 1],
+ right_record=crs[parent_idx - 1],
+ relation_type=rel_type_2
+ )
q = models.ContextRecordTree.objects.filter(
cr_parent_id=crs[2].pk, cr_id=crs[0].pk)
self.assertGreaterEqual(q.count(), 1)
@@ -992,6 +1006,11 @@ class RecordRelationsTest(ContextRecordInit, TestCase):
# verify tree generation
full_trees = [
[10, 5, 3, 2],
+ [11, 5, 3, 2],
+ [12, 5, 3, 2],
+ [12, 13, 14, 2],
+ [10, 5, 14, 2],
+ [10, 14],
[10, 5, 3, 1],
[9, 5, 3, 2],
[9, 5, 3, 1],
@@ -1004,53 +1023,6 @@ class RecordRelationsTest(ContextRecordInit, TestCase):
]
self._test_tree_generation(0, full_trees)
trees = [
- [10, 5, 3, 2],
- [10, 5, 3, 1],
- [9, 5, 3, 2],
- [9, 5, 3, 1],
- [8, 4, 3, 2],
- [8, 4, 3, 1],
- [7, 4, 3, 2],
- [7, 4, 3, 1],
- [6, 4, 3, 2],
- [6, 4, 3, 1],
- ]
- self._test_tree_generation(1, trees)
- trees = [
- [10, 5, 3, 2],
- [10, 5, 3, 1],
- [9, 5, 3, 2],
- [9, 5, 3, 1],
- [8, 4, 3, 2],
- [8, 4, 3, 1],
- [7, 4, 3, 2],
- [7, 4, 3, 1],
- [6, 4, 3, 2],
- [6, 4, 3, 1],
- ]
- self._test_tree_generation(2, trees)
- trees = [
- [8, 4, 3, 2],
- [8, 4, 3, 1],
- [7, 4, 3, 2],
- [7, 4, 3, 1],
- [6, 4, 3, 2],
- [6, 4, 3, 1],
- ]
- self._test_tree_generation(3, trees)
- trees = [
- [10, 5, 3, 2],
- [10, 5, 3, 1],
- [9, 5, 3, 2],
- [9, 5, 3, 1],
- ]
- self._test_tree_generation(4, trees)
- trees = [
- [6, 4, 3, 2],
- [6, 4, 3, 1],
- ]
- self._test_tree_generation(5, trees)
- trees = [
[7, 4, 3, 2],
[7, 4, 3, 1],
]
@@ -1075,8 +1047,33 @@ class RecordRelationsTest(ContextRecordInit, TestCase):
models.ContextRecordTree.regenerate_all()
self._test_tree_(full_trees, "'FULL GENERATION'")
- # test remove a Node
- # test EQUIV
+ # test remove a node
+ nb = models.ContextRecordTree.objects.filter(
+ cr_parent=crs[6 - 1], cr=crs[3 - 1]).count()
+ self.assertEqual(nb, 1)
+ models.RecordRelations.objects.filter(
+ left_record=crs[3 - 1],
+ right_record=crs[4 - 1]
+ ).delete()
+ models.ContextRecordTree.update(crs[3 - 1].pk)
+ models.ContextRecordTree.update(crs[4 - 1].pk)
+ nb = models.ContextRecordTree.objects.filter(
+ cr_parent=crs[6 - 1], cr=crs[3 - 1]).count()
+ self.assertEqual(nb, 0)
+
+ # test remove a node (update equal links)
+ nb = models.ContextRecordTree.objects.filter(
+ cr_parent=crs[10 - 1], cr=crs[14 - 1]).count()
+ self.assertEqual(nb, 1)
+ models.RecordRelations.objects.filter(
+ left_record=crs[3 - 1],
+ right_record=crs[5 - 1]
+ ).delete()
+ models.ContextRecordTree.update(crs[3 - 1].pk)
+ models.ContextRecordTree.update(crs[5 - 1].pk)
+ nb = models.ContextRecordTree.objects.filter(
+ cr_parent=crs[10 - 1], cr=crs[14 - 1]).count()
+ self.assertEqual(nb, 0)
def _test_tree_(self, test_trees, context_record):
crs = self.context_records