From 521ffd5d4140295265d5f3332f045bf4ad637388 Mon Sep 17 00:00:00 2001 From: Salvo 'LtWorf' Tomaselli Date: Wed, 18 Nov 2015 00:05:01 +0100 Subject: [PATCH] Reduce amount of useless copies In case of a rename, the original relation and the resulting relations are pointing to the same set. In case of functions that change the relation, such as insert, a copy is created to be able to write on it. But when writing on the other relation a new copy would have been made too. This fixes it, now when changing one relation, the other is marked as writable as well. --- relational/relation.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/relational/relation.py b/relational/relation.py index d08142a..0b18e1a 100644 --- a/relational/relation.py +++ b/relational/relation.py @@ -54,6 +54,7 @@ class Relation (object): def __init__(self, filename=""): self._readonly = False + self._copy = None self.content = set() if len(filename) == 0: # Empty relation @@ -64,15 +65,29 @@ class Relation (object): self.header = Header(next(reader)) # read 1st line iterator = ((self.insert(i) for i in reader)) deque(iterator, maxlen=0) + def _make_duplicate(self, copy): + '''Flag that the relation "copy" is pointing + to the same set as this relation.''' + + self._readonly = True + copy._readonly = True + copy._copy = self + self._copy = copy def _make_writable(self, copy_content=True): '''If this relation is marked as readonly, this - method will copy the content to make it writable too''' + method will copy the content to make it writable too + + if copy_content is set to false, the caller must + separately copy the content.''' if self._readonly: + self._readonly = False + self._copy._readonly = False + self._copy = None + if copy_content: self.content = set(self.content) - self._readonly = False def __iter__(self): return iter(self.content) @@ -195,8 +210,7 @@ class Relation (object): newt.header = self.header.rename(params) newt.content = self.content - newt._readonly = True - self._readonly = True + self._make_duplicate(newt) return newt def intersection(self, other):