Beispiel #1
0
    def applyTest(self, old, delta, new):
        s1 = RCSStream(old)
        self.assertEqual(s1.get_text(), old)
        s1.apply_diff(delta)
        self.assertEqual(s1.get_text(), new)

        s2 = RCSStream(old)
        self.assertEqual(s2.get_text(), old)
        s2.invert_diff(delta)
        self.assertEqual(s2.get_text(), new)
Beispiel #2
0
  def applyTest(self, old, delta, new):
    s1 = RCSStream(old)
    self.assertEqual(s1.get_text(), old)
    s1.apply_diff(delta)
    self.assertEqual(s1.get_text(), new)

    s2 = RCSStream(old)
    self.assertEqual(s2.get_text(), old)
    s2.invert_diff(delta)
    self.assertEqual(s2.get_text(), new)
Beispiel #3
0
  def set_revision_info(self, rev, log, text):
    revrec = self.revrecs.get(rev)

    if revrec is None:
      return

    base_rev = revrec.base
    if base_rev is None:
      # This must be the last revision on trunk, for which the
      # fulltext is stored directly in the RCS file:
      assert self.last_revrec is None
      if revrec.mark is not None:
        revrec.write_blob(self.blobfile, text)
      if revrec.is_needed():
        self.last_revrec = revrec
        self.last_rcsstream = RCSStream(text)
    elif self.last_revrec is not None and base_rev == self.last_revrec.rev:
      # Our base revision is stored in self.last_rcsstream.
      self.last_revrec.refs.remove(rev)
      if self.last_revrec.is_needed():
        if not self.last_revrec.is_written():
          self.last_revrec.write(
              self.fulltext_file, self.last_rcsstream.get_text()
              )
      self.last_rcsstream.apply_diff(text)
      if revrec.mark is not None:
        revrec.write_blob(self.blobfile, self.last_rcsstream.get_text())
      if revrec.is_needed():
        self.last_revrec = revrec
      else:
        self.last_revrec = None
        self.last_rcsstream = None
    else:
      # Our base revision is not stored in self.last_rcsstream; it
      # will have to be obtained from elsewhere.

      # Store the old last_rcsstream if necessary:
      if self.last_revrec is not None:
        if not self.last_revrec.is_written():
          self.last_revrec.write(
              self.fulltext_file, self.last_rcsstream.get_text()
              )
        self.last_revrec = None
        self.last_rcsstream = None

      base_revrec = self[base_rev]
      rcsstream = RCSStream(base_revrec.read_fulltext())
      base_revrec.refs.remove(rev)
      rcsstream.apply_diff(text)
      if revrec.mark is not None:
        revrec.write_blob(self.blobfile, rcsstream.get_text())
      if revrec.is_needed():
        self.last_revrec = revrec
        self.last_rcsstream = rcsstream
      del rcsstream
Beispiel #4
0
  def set_revision_info(self, rev, log, text):
    revrec = self.revrecs.get(rev)

    if revrec is None:
      return

    base_rev = revrec.base
    if base_rev is None:
      # This must be the last revision on trunk, for which the
      # fulltext is stored directly in the RCS file:
      assert self.last_revrec is None
      if revrec.mark is not None:
        revrec.write_blob(self.blobfile, text)
      if revrec.is_needed():
        self.last_revrec = revrec
        self.last_rcsstream = RCSStream(text)
    elif self.last_revrec is not None and base_rev == self.last_revrec.rev:
      # Our base revision is stored in self.last_rcsstream.
      self.last_revrec.refs.remove(rev)
      if self.last_revrec.is_needed():
        if not self.last_revrec.is_written():
          self.last_revrec.write(
              self.fulltext_file, self.last_rcsstream.get_text()
              )
      self.last_rcsstream.apply_diff(text)
      if revrec.mark is not None:
        revrec.write_blob(self.blobfile, self.last_rcsstream.get_text())
      if revrec.is_needed():
        self.last_revrec = revrec
      else:
        self.last_revrec = None
        self.last_rcsstream = None
    else:
      # Our base revision is not stored in self.last_rcsstream; it
      # will have to be obtained from elsewhere.

      # Store the old last_rcsstream if necessary:
      if self.last_revrec is not None:
        if not self.last_revrec.is_written():
          self.last_revrec.write(
              self.fulltext_file, self.last_rcsstream.get_text()
              )
        self.last_revrec = None
        self.last_rcsstream = None

      base_revrec = self[base_rev]
      rcsstream = RCSStream(base_revrec.read_fulltext())
      base_revrec.refs.remove(rev)
      rcsstream.apply_diff(text)
      if revrec.mark is not None:
        revrec.write_blob(self.blobfile, rcsstream.get_text())
      if revrec.is_needed():
        self.last_revrec = revrec
        self.last_rcsstream = rcsstream
      del rcsstream
Beispiel #5
0
 def checkout(self, text_record_db):
     base_text = text_record_db[self.pred_id].checkout(text_record_db)
     rcs_stream = RCSStream(base_text)
     delta_text = text_record_db.delta_db[self.id]
     rcs_stream.apply_diff(delta_text)
     text = rcs_stream.get_text()
     del rcs_stream
     self.refcount -= 1
     if self.refcount == 0:
         # This text will never be needed again; just delete ourselves
         # without ever having stored the fulltext to the checkout
         # database:
         del text_record_db[self.id]
     else:
         # Store a new CheckedOutTextRecord in place of ourselves:
         text_record_db.checkout_db['%x' % self.id] = text
         new_text_record = CheckedOutTextRecord(self.id)
         new_text_record.refcount = self.refcount
         text_record_db.replace(new_text_record)
     return text
Beispiel #6
0
 def checkout(self, text_record_db):
   base_text = text_record_db[self.pred_id].checkout(text_record_db)
   co = RCSStream(base_text)
   delta_text = text_record_db.delta_db[self.id]
   co.apply_diff(delta_text)
   text = co.get_text()
   del co
   self.refcount -= 1
   if self.refcount == 0:
     # This text will never be needed again; just delete ourselves
     # without ever having stored the fulltext to the checkout
     # database:
     del text_record_db[self.id]
   else:
     # Store a new CheckedOutTextRecord in place of ourselves:
     text_record_db.checkout_db['%x' % self.id] = text
     new_text_record = CheckedOutTextRecord(self.id)
     new_text_record.refcount = self.refcount
     text_record_db.replace(new_text_record)
   return text
Beispiel #7
0
class WriteBlobSink(Sink):
  def __init__(self, blobfile, marks):
    self.blobfile = blobfile

    # A map {rev : RevRecord} for all of the revisions whose fulltext
    # will still be needed:
    self.revrecs = {}

    # The revisions that need marks will definitely be needed, so
    # create records for them now (the rest will be filled in while
    # reading the RCS file):
    for (rev, mark) in marks.items():
      self.revrecs[rev] = RevRecord(rev, mark)

    # The RevRecord of the last fulltext that has been reconstructed,
    # if it still is_needed():
    self.last_revrec = None
    # An RCSStream holding the fulltext of last_revrec:
    self.last_rcsstream = None

    # A file to temporarily hold the fulltexts of revisions for which
    # no blobs are needed:
    self.fulltext_file = tempfile.TemporaryFile()

  def __getitem__(self, rev):
    try:
      return self.revrecs[rev]
    except KeyError:
      revrec = RevRecord(rev)
      self.revrecs[rev] = revrec
      return revrec

  def define_revision(self, rev, timestamp, author, state, branches, next):
    revrec = self[rev]

    if next is not None:
      revrec.refs.add(next)

    revrec.refs.update(branches)

    for dependent_rev in revrec.refs:
      dependent_revrec = self[dependent_rev]
      assert dependent_revrec.base is None
      dependent_revrec.base = rev

  def tree_completed(self):
    """Remove unneeded RevRecords.

    Remove the RevRecords for any revisions whose fulltext will not be
    needed (neither as blob output nor as the base of another needed
    revision)."""

    revrecs_to_remove = [
        revrec
        for revrec in self.revrecs.itervalues()
        if not revrec.is_needed()
        ]
    while revrecs_to_remove:
      revrec = revrecs_to_remove.pop()
      del self.revrecs[revrec.rev]
      if revrec.base is not None:
        base_revrec = self[revrec.base]
        base_revrec.refs.remove(revrec.rev)
        if not base_revrec.is_needed():
          revrecs_to_remove.append(base_revrec)

  def set_revision_info(self, rev, log, text):
    revrec = self.revrecs.get(rev)

    if revrec is None:
      return

    base_rev = revrec.base
    if base_rev is None:
      # This must be the last revision on trunk, for which the
      # fulltext is stored directly in the RCS file:
      assert self.last_revrec is None
      if revrec.mark is not None:
        revrec.write_blob(self.blobfile, text)
      if revrec.is_needed():
        self.last_revrec = revrec
        self.last_rcsstream = RCSStream(text)
    elif self.last_revrec is not None and base_rev == self.last_revrec.rev:
      # Our base revision is stored in self.last_rcsstream.
      self.last_revrec.refs.remove(rev)
      if self.last_revrec.is_needed() and not self.last_revrec.is_written():
        self.last_revrec.write(
            self.fulltext_file, self.last_rcsstream.get_text()
            )
      self.last_rcsstream.apply_diff(text)
      if revrec.mark is not None:
        revrec.write_blob(self.blobfile, self.last_rcsstream.get_text())
      if revrec.is_needed():
        self.last_revrec = revrec
      else:
        self.last_revrec = None
        self.last_rcsstream = None
    else:
      # Our base revision is not stored in self.last_rcsstream; it
      # will have to be obtained from elsewhere.

      # Store the old last_rcsstream if necessary:
      if self.last_revrec is not None:
        if not self.last_revrec.is_written():
          self.last_revrec.write(
              self.fulltext_file, self.last_rcsstream.get_text()
              )
        self.last_revrec = None
        self.last_rcsstream = None

      base_revrec = self[base_rev]
      rcsstream = RCSStream(base_revrec.read_fulltext())
      base_revrec.refs.remove(rev)
      rcsstream.apply_diff(text)
      if revrec.mark is not None:
        revrec.write_blob(self.blobfile, rcsstream.get_text())
      if revrec.is_needed():
        self.last_revrec = revrec
        self.last_rcsstream = rcsstream
      del rcsstream

  def parse_completed(self):
    self.fulltext_file.close()
Beispiel #8
0
class WriteBlobSink(Sink):
    def __init__(self, blobfile, marks):
        self.blobfile = blobfile

        # A map {rev : RevRecord} for all of the revisions whose fulltext
        # will still be needed:
        self.revrecs = {}

        # The revisions that need marks will definitely be needed, so
        # create records for them now (the rest will be filled in while
        # reading the RCS file):
        for (rev, mark) in marks.items():
            self.revrecs[rev] = RevRecord(rev, mark)

        # The RevRecord of the last fulltext that has been reconstructed,
        # if it still is_needed():
        self.last_revrec = None
        # An RCSStream holding the fulltext of last_revrec:
        self.last_rcsstream = None

        # A file to temporarily hold the fulltexts of revisions for which
        # no blobs are needed:
        self.fulltext_file = tempfile.TemporaryFile()

    def __getitem__(self, rev):
        try:
            return self.revrecs[rev]
        except KeyError:
            revrec = RevRecord(rev)
            self.revrecs[rev] = revrec
            return revrec

    def define_revision(self, rev, timestamp, author, state, branches, next):
        revrec = self[rev]

        if next is not None:
            revrec.refs.add(next)

        revrec.refs.update(branches)

        for dependent_rev in revrec.refs:
            dependent_revrec = self[dependent_rev]
            assert dependent_revrec.base is None
            dependent_revrec.base = rev

    def tree_completed(self):
        """Remove unneeded RevRecords.

    Remove the RevRecords for any revisions whose fulltext will not be
    needed (neither as blob output nor as the base of another needed
    revision)."""

        revrecs_to_remove = [
            revrec for revrec in self.revrecs.itervalues()
            if not revrec.is_needed()
        ]
        while revrecs_to_remove:
            revrec = revrecs_to_remove.pop()
            del self.revrecs[revrec.rev]
            base_revrec = self[revrec.base]
            base_revrec.refs.remove(revrec.rev)
            if not base_revrec.is_needed():
                revrecs_to_remove.append(base_revrec)

    def set_revision_info(self, rev, log, text):
        revrec = self.revrecs.get(rev)

        if revrec is None:
            return

        base_rev = revrec.base
        if base_rev is None:
            # This must be the last revision on trunk, for which the
            # fulltext is stored directly in the RCS file:
            assert self.last_revrec is None
            if revrec.mark is not None:
                revrec.write_blob(self.blobfile, text)
            if revrec.is_needed():
                self.last_revrec = revrec
                self.last_rcsstream = RCSStream(text)
        elif self.last_revrec is not None and base_rev == self.last_revrec.rev:
            # Our base revision is stored in self.last_rcsstream.
            self.last_revrec.refs.remove(rev)
            if self.last_revrec.is_needed():
                if not self.last_revrec.is_written():
                    self.last_revrec.write(self.fulltext_file,
                                           self.last_rcsstream.get_text())
            self.last_rcsstream.apply_diff(text)
            if revrec.mark is not None:
                revrec.write_blob(self.blobfile,
                                  self.last_rcsstream.get_text())
            if revrec.is_needed():
                self.last_revrec = revrec
            else:
                self.last_revrec = None
                self.last_rcsstream = None
        else:
            # Our base revision is not stored in self.last_rcsstream; it
            # will have to be obtained from elsewhere.

            # Store the old last_rcsstream if necessary:
            if self.last_revrec is not None:
                if not self.last_revrec.is_written():
                    self.last_revrec.write(self.fulltext_file,
                                           self.last_rcsstream.get_text())
                self.last_revrec = None
                self.last_rcsstream = None

            base_revrec = self[base_rev]
            rcsstream = RCSStream(base_revrec.read_fulltext())
            base_revrec.refs.remove(rev)
            rcsstream.apply_diff(text)
            if revrec.mark is not None:
                revrec.write_blob(self.blobfile, rcsstream.get_text())
            if revrec.is_needed():
                self.last_revrec = revrec
                self.last_rcsstream = rcsstream
            del rcsstream

    def parse_completed(self):
        self.fulltext_file.close()