Esempio n. 1
0
    def _merge_change(self, s, mid, head):
        lstate = self.socket[s][Request][mid]
        lstate['head'] = head

        self.socket[s][UpdateInfo]['head'] = head

        if self.co.lcrepo.has_key(head):
            named, modified, added, deleted = \
                   handles_in_branch(self.co, lstate['heads'], [head], None)
            self._update_checks(s, mid, named, modified)
            self._update_handle_list(s, lstate, named, modified, added,
                                     deleted)
            self._update_finish(s, lstate)
            self.socket[s][UpdateInfo]['head'] = head
            self.rs.doneflag.set()
            return 1

        rid = self._get_change(s, head)
        self.socket[s][Request][rid] = {
            'request': 'get change',
            'changenum': head,
            'ref': mid
        }
        lstate['requests'][head] = 1
        lstate['count'] = 1
        return 0
Esempio n. 2
0
    def _commit_phase_1(self, s, mid):
        request = self.socket[s][Response][mid]
        txn = request['txn']
        head = request['cur head']

        # if this change is already committed then we have nothing to do
        if self.branchmapdb.has_key(request['head']) and is_ancestor(
                self, request['head'], head, None):
            request['no phase 2'] = 1
            return

        sync_history(self, request['head'], txn, cache=request['changes'])

        if self.config.getboolean('control', 'backup'):
            if not is_ancestor(self, request['cur head'], request['head'],
                               txn):
                raise HistoryError, 'not an incremental backup'

            point = request['head']
            while point != rootnode:
                if point == request['cur head']:
                    break
                pinfo = bdecode(self.lcrepo.get(point, txn=txn))
                if not clean_merge_point(pinfo):
                    raise HistoryError, 'not an incremental backup'
                point = pinfo['precursors'][0]

        modified = handles_in_branch(self, [head], [request['head']], txn)[1]
        unlocked = self._lock_files(s, mid, modified)

        # bump the reference count by the locks we don't have
        request['count'] += len(unlocked)

        # mark all the diff requests which have to wait until we get the lock
        request['diff queue'] = {}
        for handle in unlocked:
            if request['diffs'].has_key(handle):
                request['diff queue'][handle] = 1

        # request all the related file diffs
        for handle, changes in request['diffs'].items():
            if request['diff queue'].has_key(handle):
                request['diff queue'][handle] = changes.keys()
                continue
            requested = 0
            for change in changes.keys():
                requested = 1
                self._queue_diff(s, change, handle, mid)
            request['count'] += requested
        self._get_diff(s, mid)

        # denote the merge checks we have to do later
        rmodified = request['modified'] = {}
        for handle in modified:
            rmodified[handle] = 0
Esempio n. 3
0
    def _commit_phase_1(self, s, mid):
        request = self.socket[s][Response][mid]
        txn = request['txn']
        head = request['cur head']

        # if this change is already committed then we have nothing to do
        if self.branchmapdb.has_key(request['head']) and is_ancestor(self, request['head'], head, None):
            request['no phase 2'] = 1
            return

        sync_history(self, request['head'], txn, cache=request['changes'])

        if self.config.getboolean('control', 'backup'):
            if not is_ancestor(self, request['cur head'], request['head'], txn):
                raise HistoryError, 'not an incremental backup'

            point = request['head']
            while point != rootnode:
                if point == request['cur head']:
                    break
                pinfo = bdecode(self.lcrepo.get(point, txn=txn))
                if not clean_merge_point(pinfo):
                    raise HistoryError, 'not an incremental backup'
                point = pinfo['precursors'][0]

        modified = handles_in_branch(self, [head], [request['head']], txn)[1]
        unlocked = self._lock_files(s, mid, modified)

        # bump the reference count by the locks we don't have
        request['count'] += len(unlocked)

        # mark all the diff requests which have to wait until we get the lock
        request['diff queue'] = {}
        for handle in unlocked:
            if request['diffs'].has_key(handle):
                request['diff queue'][handle] = 1

        # request all the related file diffs
        for handle, changes in request['diffs'].items():
            if request['diff queue'].has_key(handle):
                request['diff queue'][handle] = changes.keys()
                continue
            requested = 0
            for change in changes.keys():
                requested = 1
                self._queue_diff(s, change, handle, mid)
            request['count'] += requested
        self._get_diff(s, mid)

        # denote the merge checks we have to do later
        rmodified = request['modified'] = {}
        for handle in modified:
            rmodified[handle] = 0
Esempio n. 4
0
    def _merge_change(self, s, mid, head):
        lstate = self.socket[s][Request][mid]
        lstate['head'] = head

        self.socket[s][UpdateInfo]['head'] = head

        if self.co.lcrepo.has_key(head):
            named, modified, added, deleted = \
                   handles_in_branch(self.co, lstate['heads'], [head], None)
            self._update_checks(s, mid, named, modified)
            self._update_handle_list(s, lstate, named, modified, added, deleted)
            self._update_finish(s, lstate)
            self.socket[s][UpdateInfo]['head'] = head
            self.rs.doneflag.set()
            return 1

        rid = self._get_change(s, head)
        self.socket[s][Request][rid] = {'request': 'get change',
                                        'changenum': head,
                                        'ref': mid}
        lstate['requests'][head] = 1
        lstate['count'] = 1
        return 0
Esempio n. 5
0
    def _response_get_change(self, s, mid, msg, rstate):
        lstate = self.socket[s][Request][rstate['ref']]
        if sha.new(msg['changeset']).digest() != rstate['changenum']:
            raise ServerError, 'bad changeset'

        # write it out, decode and eject from memory
        write_changeset(self.co, rstate['changenum'], msg['changeset'],
                        lstate['txn'])
        changeset = bdecode(msg['changeset'])
        lstate['changes'][rstate['changenum']] = changeset
        del msg['changeset']

        # get any precursors we don't have and haven't yet requested
        for change in changeset['precursors']:
            if self.co.lcrepo.has_key(change):
                continue
            if lstate['changes'].has_key(change):
                continue
            if lstate['requests'].has_key(change):
                continue
            rid = self._get_change(s, change)
            self.socket[s][Request][rid] = {'request': 'get change',
                                            'changenum': change,
                                            'ref': rstate['ref']}
            lstate['requests'][change] = 1
            lstate['count'] += 1

        # record all the diffs we'll need to request
        diffs = lstate['diffs']
        for handle, hinfo in changeset['handles'].items():
            if not hinfo.has_key('hash'):
                continue
            if not diffs.has_key(handle):
                diffs[handle] = {}
                lstate['counts'][handle] = 0
            diffs[handle][rstate['changenum']] = 1
            lstate['counts'][handle] += 1

        # clean up state
        del lstate['requests'][rstate['changenum']]
        lstate['count'] -= 1
        if lstate['count'] == 0:
            sync_history(self.co, lstate['head'], lstate['txn'],
                                    cache=lstate['changes'])
            named, modified, added, deleted = \
                   handles_in_branch(self.co,
                                     lstate['heads'], [lstate['head']],
                                     lstate['txn'], cache=lstate['changes'])
            del lstate['changes']
            self._update_checks(s, rstate['ref'], named, modified)
            self._update_handle_list(s, lstate, named, modified, added, deleted)

            handle_list = lstate['handle list']
            # get all the related file diffs
            for i in xrange(len(handle_list)-1, -1, -1):
                handle = handle_list[i][1]
                if not diffs.has_key(handle):
                    continue
                changes = diffs[handle]

                requested = 0
                for change in changes.keys():
                    requested = 1
                    self._queue_diff(s, change, handle, rstate['ref'])
                lstate['count'] += requested
            self._get_diff(s, rstate['ref'])

        if lstate['count'] == 0:
            self._update_finish(s, lstate)
            del self.socket[s][Request][rstate['ref']]
            self.rs.doneflag.set()
        return 1
Esempio n. 6
0
    def _response_get_change(self, s, mid, msg, rstate):
        lstate = self.socket[s][Request][rstate['ref']]
        if sha.new(msg['changeset']).digest() != rstate['changenum']:
            raise ServerError, 'bad changeset'

        # write it out, decode and eject from memory
        write_changeset(self.co, rstate['changenum'], msg['changeset'],
                        lstate['txn'])
        changeset = bdecode(msg['changeset'])
        lstate['changes'][rstate['changenum']] = changeset
        del msg['changeset']

        # get any precursors we don't have and haven't yet requested
        for change in changeset['precursors']:
            if self.co.lcrepo.has_key(change):
                continue
            if lstate['changes'].has_key(change):
                continue
            if lstate['requests'].has_key(change):
                continue
            rid = self._get_change(s, change)
            self.socket[s][Request][rid] = {
                'request': 'get change',
                'changenum': change,
                'ref': rstate['ref']
            }
            lstate['requests'][change] = 1
            lstate['count'] += 1

        # record all the diffs we'll need to request
        diffs = lstate['diffs']
        for handle, hinfo in changeset['handles'].items():
            if not hinfo.has_key('hash'):
                continue
            if not diffs.has_key(handle):
                diffs[handle] = {}
                lstate['counts'][handle] = 0
            diffs[handle][rstate['changenum']] = 1
            lstate['counts'][handle] += 1

        # clean up state
        del lstate['requests'][rstate['changenum']]
        lstate['count'] -= 1
        if lstate['count'] == 0:
            sync_history(self.co,
                         lstate['head'],
                         lstate['txn'],
                         cache=lstate['changes'])
            named, modified, added, deleted = \
                   handles_in_branch(self.co,
                                     lstate['heads'], [lstate['head']],
                                     lstate['txn'], cache=lstate['changes'])
            del lstate['changes']
            self._update_checks(s, rstate['ref'], named, modified)
            self._update_handle_list(s, lstate, named, modified, added,
                                     deleted)

            handle_list = lstate['handle list']
            # get all the related file diffs
            for i in xrange(len(handle_list) - 1, -1, -1):
                handle = handle_list[i][1]
                if not diffs.has_key(handle):
                    continue
                changes = diffs[handle]

                requested = 0
                for change in changes.keys():
                    requested = 1
                    self._queue_diff(s, change, handle, rstate['ref'])
                lstate['count'] += requested
            self._get_diff(s, rstate['ref'])

        if lstate['count'] == 0:
            self._update_finish(s, lstate)
            del self.socket[s][Request][rstate['ref']]
            self.rs.doneflag.set()
        return 1