From mercurial-bounces@selenic.com Thu Sep 1 07:01:32 2005
Return-Path: <mercurial-bounces@selenic.com>
X-Original-To: bos@serpentine.com
Delivered-To: bos@serpentine.com
Received: from waste.org (waste.org [216.27.176.166]) by
demesne.serpentine.com (Postfix) with ESMTP id 3616A20B571 for
<bos@serpentine.com>; Thu, 1 Sep 2005 07:01:32 -0700 (PDT)
Received: from waste.org (localhost [127.0.0.1]) by waste.org
(8.13.4/8.13.4/Debian-3) with ESMTP id j81DxodQ028829; Thu, 1 Sep 2005
08:59:51 -0500
Received: from web32904.mail.mud.yahoo.com (web32904.mail.mud.yahoo.com
[68.142.206.51]) by waste.org (8.13.4/8.13.4/Debian-3) with SMTP id
j81DxnNA028824 for <mercurial@selenic.com>; Thu, 1 Sep 2005 08:59:49 -0500
Received: (qmail 25859 invoked by uid 60001); 1 Sep 2005 13:59:17 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com;
h=Message-ID:Received:Date:From:Subject:To:In-Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding;
b=O6sELrlCknW3M/gKVqijWs82e/CbDEum1sEitcuLKXaP9dHU175PszOqMgcSKykMY+BVXtcH3NeaXLM3FyBmqNkoPAvesezyFbgQsHSM1S028oOexybCKMvtGQJmz66hzd1fDb0QoPj1gCcGU2VDevQaOesSmo1xF9jJwy2LlLE=
;
Message-ID: <20050901135917.25856.qmail@web32904.mail.mud.yahoo.com>
Received: from [60.48.222.94] by web32904.mail.mud.yahoo.com via HTTP; Thu,
01 Sep 2005 06:59:17 PDT
Date: Thu, 1 Sep 2005 06:59:17 -0700 (PDT)
From: TK Soh <teekaysoh@yahoo.com>
To: mercurial@selenic.com
In-Reply-To: <20050828075808.GO27787@waste.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
X-Virus-Scanned: by amavisd-new
Subject: Re: add -p to hg tip
X-BeenThere: mercurial@selenic.com
X-Mailman-Version: 2.1.5
Precedence: list
List-Id: mercurial.selenic.com
List-Unsubscribe: <http://selenic.com/mailman/listinfo/mercurial>,
<mailto:mercurial-request@selenic.com?subject=unsubscribe>
List-Archive: <http://www.selenic.com/pipermail/mercurial>
List-Post: <mailto:mercurial@selenic.com>
List-Help: <mailto:mercurial-request@selenic.com?subject=help>
List-Subscribe: <http://selenic.com/mailman/listinfo/mercurial>,
<mailto:mercurial-request@selenic.com?subject=subscribe>
Sender: mercurial-bounces@selenic.com
Errors-To: mercurial-bounces@selenic.com
X-Spam-Checker-Version: SpamAssassin 3.0.4 (2005-06-05) on
demesne.serpentine.com
X-Spam-Level:
X-Spam-Status: No, score=-1.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham
version=3.0.4
X-Evolution-Source: imap://bos@www.serpentine.com/
Content-Transfer-Encoding: 8bit
# manifest.py - manifest revision class for mercurial
#
# Copyright 2005 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
import sys, struct
from revlog import *
from demandload import *
demandload(globals(), "bisect")
class manifest(revlog):
def __init__(self, opener):
self.mapcache = None
self.listcache = None
self.addlist = None
revlog.__init__(self, opener, "00manifest.i", "00manifest.d")
def read(self, node):
if node == nullid: return {} # don't upset local cache
if self.mapcache and self.mapcache[0] == node:
return self.mapcache[1]
text = self.revision(node)
map = {}
flag = {}
self.listcache = (text, text.splitlines(1))
for l in self.listcache[1]:
(f, n) = l.split('\0')
map[f] = bin(n[:40])
flag[f] = (n[40:-1] == "x")
self.mapcache = (node, map, flag)
return map
def readflags(self, node):
if node == nullid: return {} # don't upset local cache
if not self.mapcache or self.mapcache[0] != node:
self.read(node)
return self.mapcache[2]
def diff(self, a, b):
# this is sneaky, as we're not actually using a and b
if self.listcache and self.addlist and self.listcache[0] == a:
d = mdiff.diff(self.listcache[1], self.addlist, 1)
if mdiff.patch(a, d) != b:
raise AssertionError("sortdiff failed!")
return d
else:
return mdiff.textdiff(a, b)
def add(self, map, flags, transaction, link, p1=None, p2=None,
changed=None):
# directly generate the mdiff delta from the data collected during
# the bisect loop below
def gendelta(delta):
i = 0
result = []
while i < len(delta):
start = delta[i][2]
end = delta[i][3]
l = delta[i][4]
if l == None:
l = ""
while i < len(delta) - 1 and start <= delta[i+1][2] \
and end >= delta[i+1][2]:
if delta[i+1][3] > end:
end = delta[i+1][3]
if delta[i+1][4]:
l += delta[i+1][4]
i += 1
result.append(struct.pack(">lll", start, end, len(l)) + l)
i += 1
return result
# apply the changes collected during the bisect loop to our addlist
def addlistdelta(addlist, delta):
# apply the deltas to the addlist. start from the bottom up
# so changes to the offsets don't mess things up.
i = len(delta)
while i > 0:
i -= 1
start = delta[i][0]
end = delta[i][1]
if delta[i][4]:
addlist[start:end] = [delta[i][4]]
else:
del addlist[start:end]
return addlist
# calculate the byte offset of the start of each line in the
# manifest
def calcoffsets(addlist):
offsets = [0] * (len(addlist) + 1)
offset = 0
i = 0
while i < len(addlist):
offsets[i] = offset
offset += len(addlist[i])
i += 1
offsets[i] = offset
return offsets
# if we're using the listcache, make sure it is valid and
# parented by the same node we're diffing against
if not changed or not self.listcache or not p1 or \
self.mapcache[0] != p1:
files = map.keys()
files.sort()
self.addlist = ["%s\000%s%s\n" %
(f, hex(map[f]), flags[f] and "x" or '')
for f in files]
cachedelta = None
else:
addlist = self.listcache[1]
# find the starting offset for each line in the add list
offsets = calcoffsets(addlist)
# combine the changed lists into one list for sorting
work = [[x, 0] for x in changed[0]]
work[len(work):] = [[x, 1] for x in changed[1]]
work.sort()
delta = []
bs = 0
for w in work:
f = w[0]
# bs will either be the index of the item or the insert point
bs = bisect.bisect(addlist, f, bs)
if bs < len(addlist):
fn = addlist[bs][:addlist[bs].index('\0')]
else:
fn = None
if w[1] == 0:
l = "%s\000%s%s\n" % (f, hex(map[f]),
flags[f] and "x" or '')
else:
l = None
start = bs
if fn != f:
# item not found, insert a new one
end = bs
if w[1] == 1:
raise AssertionError(
"failed to remove %s from manifest\n" % f)
else:
# item is found, replace/delete the existing line
end = bs + 1
delta.append([start, end, offsets[start], offsets[end], l])
self.addlist = addlistdelta(addlist, delta)
if self.mapcache[0] == self.tip():
cachedelta = "".join(gendelta(delta))
else:
cachedelta = None
text = "".join(self.addlist)
if cachedelta and mdiff.patch(self.listcache[0], cachedelta) != text:
raise AssertionError("manifest delta failure\n")
n = self.addrevision(text, transaction, link, p1, p2, cachedelta)
self.mapcache = (n, map, flags)
self.listcache = (text, self.addlist)
self.addlist = None
return n