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.
This commit is contained in:
Salvo 'LtWorf' Tomaselli 2015-11-18 00:05:01 +01:00
parent ff3a5935fc
commit 521ffd5d41

View File

@ -54,6 +54,7 @@ class Relation (object):
def __init__(self, filename=""): def __init__(self, filename=""):
self._readonly = False self._readonly = False
self._copy = None
self.content = set() self.content = set()
if len(filename) == 0: # Empty relation if len(filename) == 0: # Empty relation
@ -64,15 +65,29 @@ class Relation (object):
self.header = Header(next(reader)) # read 1st line self.header = Header(next(reader)) # read 1st line
iterator = ((self.insert(i) for i in reader)) iterator = ((self.insert(i) for i in reader))
deque(iterator, maxlen=0) 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): def _make_writable(self, copy_content=True):
'''If this relation is marked as readonly, this '''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: if self._readonly:
self._readonly = False
self._copy._readonly = False
self._copy = None
if copy_content: if copy_content:
self.content = set(self.content) self.content = set(self.content)
self._readonly = False
def __iter__(self): def __iter__(self):
return iter(self.content) return iter(self.content)
@ -195,8 +210,7 @@ class Relation (object):
newt.header = self.header.rename(params) newt.header = self.header.rename(params)
newt.content = self.content newt.content = self.content
newt._readonly = True self._make_duplicate(newt)
self._readonly = True
return newt return newt
def intersection(self, other): def intersection(self, other):