Skip to content

Commit 62559dd

Browse files
author
Richard Jones
committed
fixed the journal bloat from multilink changes
we just log the add or remove operations, not the whole list
1 parent ef98a08 commit 62559dd

File tree

3 files changed

+66
-37
lines changed

3 files changed

+66
-37
lines changed

CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ Feature:
3939
. switched to using a session-based web login
4040
. made mailgw handle set and modify operations on multilinks (bug #579094)
4141
. all storage-specific code (ie. backend) is now implemented by the backends
42+
. fixed the journal bloat from multilink changes - we just log the add or
43+
remove operations, not the whole list
44+
4245

4346
2002-06-24 0.4.2
4447
Fixed:

TODO.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ pending meta/parent bug support/implementation
1515
pending user preferences
1616
feature request #507842
1717
pending rename to "instance" to "tracker"
18-
pending journalling: fix the journal bloat
19-
related: Re-enable link backrefs from messages
18+
done journalling: fix the journal bloat
19+
pending related: Re-enable link backrefs from messages
2020
feature request #568714
2121
pending alternative user auth: at least an LDAP implementation
2222
active security overhaul: see doc/security.txt (RJ)
2323
done - switch to sessions for web authentication
24-
- authenticate over a secure connection
2524
- implement and use the new logical control mechanisms
25+
- authenticate over a secure connection
2626
- use digital signatures in mailgw
2727
active implement an RDB backend (RJ)
2828
done - further split the *dbm backends from the core code, allowing

roundup/backends/back_anydbm.py

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
#$Id: back_anydbm.py,v 1.46 2002-07-14 06:06:34 richard Exp $
18+
#$Id: back_anydbm.py,v 1.47 2002-07-14 23:18:20 richard Exp $
1919
'''
2020
This module defines a backend that saves the hyperdatabase in a database
2121
chosen by anydbm. It is guaranteed to always be available in python
@@ -876,9 +876,13 @@ class or a KeyError is raised.
876876
if node.has_key(self.db.RETIRED_FLAG):
877877
raise IndexError
878878
num_re = re.compile('^\d+$')
879-
for key, value in propvalues.items():
879+
880+
# if the journal value is to be different, store it in here
881+
journalvalues = {}
882+
883+
for propname, value in propvalues.items():
880884
# check to make sure we're not duplicating an existing key
881-
if key == self.key and node[key] != value:
885+
if propname == self.key and node[propname] != value:
882886
try:
883887
self.lookup(value)
884888
except KeyError:
@@ -889,17 +893,17 @@ class or a KeyError is raised.
889893
# this will raise the KeyError if the property isn't valid
890894
# ... we don't use getprops() here because we only care about
891895
# the writeable properties.
892-
prop = self.properties[key]
896+
prop = self.properties[propname]
893897

894898
# if the value's the same as the existing value, no sense in
895899
# doing anything
896-
if node.has_key(key) and value == node[key]:
897-
del propvalues[key]
900+
if node.has_key(propname) and value == node[propname]:
901+
del propvalues[propname]
898902
continue
899903

900904
# do stuff based on the prop type
901905
if isinstance(prop, Link):
902-
link_class = self.properties[key].classname
906+
link_class = self.properties[propname].classname
903907
# if it isn't a number, it's a key
904908
if type(value) != type(''):
905909
raise ValueError, 'link value must be String'
@@ -908,97 +912,116 @@ class or a KeyError is raised.
908912
value = self.db.classes[link_class].lookup(value)
909913
except (TypeError, KeyError):
910914
raise IndexError, 'new property "%s": %s not a %s'%(
911-
key, value, self.properties[key].classname)
915+
propname, value, self.properties[propname].classname)
912916

913917
if not self.db.hasnode(link_class, value):
914918
raise IndexError, '%s has no node %s'%(link_class, value)
915919

916-
if self.do_journal and self.properties[key].do_journal:
920+
if self.do_journal and self.properties[propname].do_journal:
917921
# register the unlink with the old linked node
918-
if node[key] is not None:
919-
self.db.addjournal(link_class, node[key], 'unlink',
920-
(self.classname, nodeid, key))
922+
if node[propname] is not None:
923+
self.db.addjournal(link_class, node[propname], 'unlink',
924+
(self.classname, nodeid, propname))
921925

922926
# register the link with the newly linked node
923927
if value is not None:
924928
self.db.addjournal(link_class, value, 'link',
925-
(self.classname, nodeid, key))
929+
(self.classname, nodeid, propname))
926930

927931
elif isinstance(prop, Multilink):
928932
if type(value) != type([]):
929-
raise TypeError, 'new property "%s" not a list of ids'%key
930-
link_class = self.properties[key].classname
933+
raise TypeError, 'new property "%s" not a list of'\
934+
' ids'%propname
935+
link_class = self.properties[propname].classname
931936
l = []
932937
for entry in value:
933938
# if it isn't a number, it's a key
934939
if type(entry) != type(''):
935940
raise ValueError, 'new property "%s" link value ' \
936-
'must be a string'%key
941+
'must be a string'%propname
937942
if not num_re.match(entry):
938943
try:
939944
entry = self.db.classes[link_class].lookup(entry)
940945
except (TypeError, KeyError):
941946
raise IndexError, 'new property "%s": %s not a %s'%(
942-
key, entry, self.properties[key].classname)
947+
propname, entry,
948+
self.properties[propname].classname)
943949
l.append(entry)
944950
value = l
945-
propvalues[key] = value
951+
propvalues[propname] = value
952+
953+
# figure the journal entry for this property
954+
add = []
955+
remove = []
946956

947957
# handle removals
948-
if node.has_key(key):
949-
l = node[key]
958+
if node.has_key(propname):
959+
l = node[propname]
950960
else:
951961
l = []
952962
for id in l[:]:
953963
if id in value:
954964
continue
955965
# register the unlink with the old linked node
956-
if self.do_journal and self.properties[key].do_journal:
966+
if self.do_journal and self.properties[propname].do_journal:
957967
self.db.addjournal(link_class, id, 'unlink',
958-
(self.classname, nodeid, key))
968+
(self.classname, nodeid, propname))
959969
l.remove(id)
970+
remove.append(id)
960971

961972
# handle additions
962973
for id in value:
963974
if not self.db.hasnode(link_class, id):
964-
raise IndexError, '%s has no node %s'%(
965-
link_class, id)
975+
raise IndexError, '%s has no node %s'%(link_class, id)
966976
if id in l:
967977
continue
968978
# register the link with the newly linked node
969-
if self.do_journal and self.properties[key].do_journal:
979+
if self.do_journal and self.properties[propname].do_journal:
970980
self.db.addjournal(link_class, id, 'link',
971-
(self.classname, nodeid, key))
981+
(self.classname, nodeid, propname))
972982
l.append(id)
983+
add.append(id)
984+
985+
# figure the journal entry
986+
l = []
987+
if add:
988+
l.append(('add', add))
989+
if remove:
990+
l.append(('remove', remove))
991+
if l:
992+
journalvalues[propname] = tuple(l)
973993

974994
elif isinstance(prop, String):
975995
if value is not None and type(value) != type(''):
976-
raise TypeError, 'new property "%s" not a string'%key
996+
raise TypeError, 'new property "%s" not a string'%propname
977997

978998
elif isinstance(prop, Password):
979999
if not isinstance(value, password.Password):
980-
raise TypeError, 'new property "%s" not a Password'% key
981-
propvalues[key] = value
1000+
raise TypeError, 'new property "%s" not a Password'%propname
1001+
propvalues[propname] = value
9821002

9831003
elif value is not None and isinstance(prop, Date):
9841004
if not isinstance(value, date.Date):
985-
raise TypeError, 'new property "%s" not a Date'% key
986-
propvalues[key] = value
1005+
raise TypeError, 'new property "%s" not a Date'% propname
1006+
propvalues[propname] = value
9871007

9881008
elif value is not None and isinstance(prop, Interval):
9891009
if not isinstance(value, date.Interval):
990-
raise TypeError, 'new property "%s" not an Interval'% key
991-
propvalues[key] = value
1010+
raise TypeError, 'new property "%s" not an '\
1011+
'Interval'%propname
1012+
propvalues[propname] = value
9921013

993-
node[key] = value
1014+
node[propname] = value
9941015

9951016
# nothing to do?
9961017
if not propvalues:
9971018
return
9981019

9991020
# do the set, and journal it
10001021
self.db.setnode(self.classname, nodeid, node)
1022+
10011023
if self.do_journal:
1024+
propvalues.update(journalvalues)
10021025
self.db.addjournal(self.classname, nodeid, 'set', propvalues)
10031026

10041027
self.fireReactors('set', nodeid, oldvalues)
@@ -1615,6 +1638,9 @@ def __init__(self, db, classname, **properties):
16151638

16161639
#
16171640
#$Log: not supported by cvs2svn $
1641+
#Revision 1.46 2002/07/14 06:06:34 richard
1642+
#Did some old TODOs
1643+
#
16181644
#Revision 1.45 2002/07/14 04:03:14 richard
16191645
#Implemented a switch to disable journalling for a Class. CGI session
16201646
#database now uses it.

0 commit comments

Comments
 (0)