Commit 3496e36e authored by Grégory Wisniewski's avatar Grégory Wisniewski

Give oid_list to deleteTransaction to take advantages of indexes.

git-svn-id: https://svn.erp5.org/repos/neo/trunk@2320 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 89a9a658
......@@ -190,7 +190,7 @@ class EventHandler(object):
def answerObjectPresent(self, conn, oid, tid):
raise UnexpectedPacketError
def deleteTransaction(self, conn, tid):
def deleteTransaction(self, conn, tid, oid_list):
raise UnexpectedPacketError
def commitTransaction(self, conn, tid):
......
......@@ -134,7 +134,7 @@ class VerificationManager(BaseServiceHandler):
for tid in self._tid_set:
uuid_set = self.verifyTransaction(tid)
if uuid_set is None:
packet = Packets.DeleteTransaction(tid)
packet = Packets.DeleteTransaction(tid, self._oid_set or [])
# Make sure that no node has this transaction.
for node in self.app.nm.getIdentifiedList():
if node.isStorage():
......
......@@ -697,12 +697,27 @@ class DeleteTransaction(Packet):
"""
Delete a transaction. PM -> S.
"""
def _encode(self, tid):
return _encodeTID(tid)
_header_format = '!8sL'
_list_entry_format = '8s'
_list_entry_len = calcsize(_list_entry_format)
def _encode(self, tid, oid_list):
body = [pack(self._header_format, tid, len(oid_list))]
body.extend(oid_list)
return ''.join(body)
def _decode(self, body):
(tid, ) = unpack('8s', body)
return (_decodeTID(tid), )
offset = self._header_len
(tid, n) = unpack(self._header_format, body[:offset])
oid_list = []
list_entry_format = self._list_entry_format
list_entry_len = self._list_entry_len
for _ in xrange(n):
next_offset = offset + list_entry_len
oid = unpack(list_entry_format, body[offset:next_offset])[0]
offset = next_offset
oid_list.append(oid)
return (tid, oid_list)
class CommitTransaction(Packet):
"""
......
......@@ -380,10 +380,9 @@ class DatabaseManager(object):
temporarily data to a finished area."""
raise NotImplementedError
def deleteTransaction(self, tid, all = False):
"""Delete a transaction specified by a given ID from a temporarily
area. If all is true, it must be deleted even from a finished
area."""
def deleteTransaction(self, tid, oid_list):
"""Delete a transaction and its content specified by a given ID and
an oid list"""
raise NotImplementedError
def deleteObject(self, oid, serial=None):
......
......@@ -500,18 +500,27 @@ class MySQLDatabaseManager(DatabaseManager):
raise
self.commit()
def deleteTransaction(self, tid, all = False):
def deleteTransaction(self, tid, oid_list):
q = self.query
tid = util.u64(tid)
u64 = util.u64
tid = u64(tid)
getPartition = self.getPartition
self.begin()
try:
q("""DELETE FROM tobj WHERE serial = %d""" % tid)
q("""DELETE FROM ttrans WHERE tid = %d""" % tid)
if all:
# Note that this can be very slow.
q("""DELETE FROM obj WHERE serial = %d""" % tid)
q("""DELETE FROM trans WHERE partition = %d AND tid = %d""" %
(self.getPartition(tid), tid))
# delete from obj using indexes
for oid in oid_list:
oid = u64(oid)
partition = getPartition(oid)
q("DELETE FROM obj WHERE partition=%(partition)d "
"AND oid = %(oid)d AND serial = %(serial)d" % {
'partition': partition,
'oid': oid,
'serial': tid,
})
except:
self.rollback()
raise
......
......@@ -82,8 +82,8 @@ class VerificationHandler(BaseMasterHandler):
'%s:%s do not exist' % (dump(oid), dump(tid)))
conn.answer(p)
def deleteTransaction(self, conn, tid):
self.app.dm.deleteTransaction(tid, all = True)
def deleteTransaction(self, conn, tid, oid_list):
self.app.dm.deleteTransaction(tid, oid_list)
def commitTransaction(self, conn, tid):
self.app.dm.finishTransaction(tid)
......
......@@ -429,17 +429,11 @@ class StorageMySQSLdbTests(NeoTestBase):
tid1, tid2 = self.getTIDs(2)
txn1, objs1 = self.getTransaction([oid1])
txn2, objs2 = self.getTransaction([oid2])
# delete only from temporary tables
self.db.storeTransaction(tid1, objs1, txn1)
self.db.storeTransaction(tid2, objs2, txn2)
self.db.finishTransaction(tid1)
self.db.deleteTransaction(tid1)
self.db.deleteTransaction(tid2)
result = self.db.getTransaction(tid1, True)
self.assertEqual(result, ([oid1], 'user', 'desc', 'ext', False))
self.assertEqual(self.db.getTransaction(tid2, True), None)
# delete from all
self.db.deleteTransaction(tid1, True)
self.db.deleteTransaction(tid1, [oid1])
self.db.deleteTransaction(tid2, [oid2])
self.assertEqual(self.db.getTransaction(tid1, True), None)
self.assertEqual(self.db.getTransaction(tid2, True), None)
......
......@@ -240,11 +240,12 @@ class StorageVerificationHandlerTests(NeoTestBase):
'deleteTransaction': None,
})
conn = self.getMasterConnection()
oid_list = [self.getOID(1), self.getOID(2)]
tid = p64(1)
self.verification.deleteTransaction(conn, tid)
self.verification.deleteTransaction(conn, tid, oid_list)
call_list = self.app.dm.mockGetNamedCalls('deleteTransaction')
self.assertEqual(len(call_list), 1)
call_list[0].checkArgs(tid, all=True)
call_list[0].checkArgs(tid, oid_list)
def test_17_commitTransaction(self):
# commit a transaction
......
......@@ -225,10 +225,10 @@ class ProtocolTests(NeoTestBase):
def test_30_deleteTransaction(self):
tid = self.getNextTID()
p = Packets.DeleteTransaction(tid)
oid_list = [self.getOID(1), self.getOID(2)]
p = Packets.DeleteTransaction(tid, oid_list)
self.assertEqual(p.getType(), Packets.DeleteTransaction)
ptid = p.decode()[0]
self.assertEqual(ptid, tid)
self.assertEqual(p.decode(), (tid, oid_list))
def test_31_commitTransaction(self):
tid = self.getNextTID()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment