Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sharedstate.git/sharedstate/sharedpython.py
diff options
context:
space:
mode:
Diffstat (limited to 'sharedstate.git/sharedstate/sharedpython.py')
-rw-r--r--sharedstate.git/sharedstate/sharedpython.py234
1 files changed, 0 insertions, 234 deletions
diff --git a/sharedstate.git/sharedstate/sharedpython.py b/sharedstate.git/sharedstate/sharedpython.py
deleted file mode 100644
index 78a622a..0000000
--- a/sharedstate.git/sharedstate/sharedpython.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# sharedpython.py, classes to aid activities in sharing a state
-# @author: Miguel Angel Alvarez, miguel@laptop.org
-# @author: Reinier Heeres
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Change log:
-#
-
-import pickle
-import difflib
-import logging
-from sharedobject import DiffRec
-_logger = logging.getLogger('sharedpython')
-
-from sharedobject import SharedObject
-
-class SharedPython(SharedObject):
-
- def __init__(self, name, helper, opt={}):
- SharedObject.__init__(self, name, helper, opt=opt)
- self._value = None
- self._picklestr = ''
-
- def _divide_change(self, c):
- """Separate the index and the string parts of the chage string"""
- if ' ' in c:
- i = c.index(' ')
- return (c[:i], c[i+1:])
- else:
- print c
- return None
-
- def inverse_diff(self, diff):
- """Return the inverse diff object"""
- d = SharedObject.inverse_diff(self, diff)
- if d == None:
- obj = self._generate_inverse_diffobj(diff.obj)
- return DiffRec(diff.version_id, diff.sender, True, obj)
-
- def _generate_inverse_diffobj(self, changes):
- ret = []
- delta = 0
- last_num = -1
- last_n_in = -1
-
- for c in changes:
- n, s = self._divide_change(c)
- l = len(s)
- num = abs(int(n))
- if num == last_num:
- n_in = last_n_in
- else:
- n_in = num + delta
- last_num = num
- last_n_in = n_in
-
- if c[0] == '+':
- ret.append('-'+str(n_in)+' '+s)
- delta += l
- elif c[0] == '-':
- ret.append('+'+str(n_in)+' '+s)
- delta -= l
- else:
- print "Unknown line type:", c
- ret = self._format_changes(ret)
- return ret
-
- def _update_interval(self, i, cs):
- """Get an 'exclusion interval' (where no other different edits are accepted) for the change cs[i]"""
- c = cs[i]
- n, d = self._divide_change(c)
- n = int(n)
- if n >= 0:
- return (n+1, n+1)
- else:
- return (abs(n), abs(n) + len(d))
-
- def _intersect(self, ia, ib):
- """function that takes 2 intervals (2 element ordered int lists) and returns whether they
- intersect and, if not, which one is bigger:
- ret > 0 => ia bigger
- ret < 0 => ib bigger
- ret = 0 => intersection"""
- assert ia[1] >= ia[0] and len(ia) == 2
- assert ib[1] >= ib[0] and len(ib) == 2
- if ia[0] > ib[1]:
- return 1 #No _intersect, ia bigger
- if ia[1] < ib[0]:
- return -1 #No _intersect, ia smaller
- return 0 #Intersect
-
- def _compatible_diffs(self, diff_a, diff_b):
- """ It returns whether two change arrays act upon the same positions, and
- cannot therefore be automatically merged without risking conflict"""
- _logger.debug("_compatible_diffs(): a=%s, b=%s", diff_a, diff_b)
- index_a = index_b = 0
- while index_a < len(diff_a) and index_b < len(diff_b):
- interval_a = self._update_interval(index_a, diff_a)
- interval_b = self._update_interval(index_b, diff_b)
- d = self._intersect(interval_a, interval_b)
- if d == 0 :
-## if diff_a[index_a] not in diff_b and diff_b[index_b] not in diff_a:
-## print "change a:'%s'\tchange_b:'%s'" % (diff_a[index_a], diff_b[index_b])
-## return False
-## elif interval_a[1] > interval_b[1]:
-## index_b += 1
-## else:
-## index_a += 1
-## ATT: More restrictive version of compatible_diffs used right now
- return False
- elif d == 1:
- index_b += 1
- elif d == -1:
- index_a += 1
- else:
- index_a += 1
- index_b += 1
- return True
-
- def _format_changes(self, changes):
- last_sign = None
- last_num = -1
- foreseen_index = -1
- res=[]
- for c in changes:
- sign = c[0]
- n, s = self._divide_change(c)
- number = abs(int(n))
- if sign == "+" and last_sign == "-" and (number == foreseen_index or number == last_num) :
- res = res[:-1]+[sign +str(last_num)+" "+s, res[-1]]
- last_sign = sign
- foreseen_index = number + len(s)
- last_num = number
- else:
- res.append(c)
- last_sign = sign
- foreseen_index = number + len(s)
- last_num = number
- return res
-
- def diff(self, new_object, old_object):
- """Generate a change array from two python objects"""
- _logger.debug("Diffing old:%s (type: %s), new: %s (type: %s)", old_object, type(old_object),
- new_object, type(new_object))
- differ = difflib.Differ()
- old = pickle.dumps(old_object)
- new = pickle.dumps(new_object)
-## _logger.debug('Old text: %s', old)
-## _logger.debug(' New text:%s', new)
- ret = []
- raw_delta = list(differ.compare(old, new))
-## _logger.debug('raw delta: %s', raw_delta)
- pos = 0
- continuous = False
- for r in raw_delta:
- if r[:2] == "+ ":
- if len(ret) > 0 and ret[-1][0] == "+" and continuous:
- ret[-1] += r[2:]
- #if 2 continuous additions occur, append at the end
- else:
- string = "+"+str(pos)+" "+r[2:]
- ret.append(string)
- continuous = True
- elif r[:2] == "- ":
- if len(ret) > 0 and ret[-1][0] == "-" and continuous:
- ret[-1] += r[2:] #append at the end
- else:
- string = "-"+str(pos)+" "+r[2:]
- ret.append(string)
- continuous = True
- pos += 1 # TODO: important change; verify
- elif r[:2] == "? ":
- pass
- else:
- continuous = False
- pos += len(r) - 2
-## _logger.debug('Ret before format changes: %s', ret)
- return self._format_changes(ret)
-
- def _apply_diff_to(self, object, diffobj):
- """ Apply a diff to a given object and return the new version
- In this case, the provided object gets modified, too."""
- old = pickle.dumps(object)
- _logger.debug("_apply_diff_to(): old=%r, diffobj=%s", old, diffobj)
- new = ""
- pos = old_pos = 0
- for c in diffobj:
- id, st = self._divide_change(c)
- pos = abs(int(id))
- new += old[old_pos:pos]
- if id[0] == "+":
-## _logger.debug("_apply_diff_to(): adding %r", st)
- new += st
- elif id[0] == "-":
-## _logger.debug("_apply_diff_to(): deleting %r", st)
- if old[pos:pos+len(st)] != st:
- exc = "Bad delete at %d, expected %s, got %r" % (pos,
- st, old[pos:pos+len(st)])
- raise Exception(exc)
- pos += len(st)
- old_pos = pos
- if pos < len(old):
- new += old[pos:]
- res = pickle.loads(new)
- _logger.debug("_apply_diff_to(): new=%r, res=%s", new, res)
- idiff = self._generate_inverse_diffobj(diffobj)
- return (res, idiff)
-
- def get_version(self, versionid):
- _logger.debug("get_version(): called with versionid = %d", versionid)
- if versionid == self._version_id:
- return self._value
- ret = self._value
- if versionid > self._version_id:
- return None
- for i in range(len(self._received_diffs)-1, self._get_diff_index(versionid), -1):
- d = self._received_diffs[i]
- idobj = self._generate_inverse_diffobj(d.obj)
- ret = self._apply_diff_to(ret, idobj)[0]
- _logger.debug("get_version(): return value: %s", ret)
- return ret