[Commits] (vajda) - reworked all dirtying code so that it is called
only once per change
commits at osafoundation.org
commits at osafoundation.org
Thu Aug 19 11:06:33 PDT 2004
Commit by: vajda
Modified files:
chandler/application/Application.py 1.259 1.260
chandler/application/Parcel.py 1.26 1.27
chandler/parcels/osaf/framework/blocks/ContainerBlocks.py 1.124 1.125
chandler/parcels/osaf/framework/blocks/calendar/CalendarBlocks.py 1.27 1.28
chandler/repository/item/Monitors.py None 1.1
chandler/repository/item/Indexes.py 1.3 1.4
chandler/repository/item/Item.py 1.151 1.152
chandler/repository/item/ItemHandler.py 1.43 1.44
chandler/repository/item/ItemRef.py 1.86 1.87
chandler/repository/item/PersistentCollections.py 1.18 1.19
chandler/repository/item/Values.py 1.13 1.14
chandler/repository/packs/schema.pack 1.19 1.20
chandler/repository/packs/schema/model/Items.namespace None 1.1
chandler/repository/packs/schema/model/Monitors.kind None 1.1
chandler/repository/packs/schema/model/Item.kind 1.14 1.15
chandler/repository/packs/schema/model/clouds/Item.cloud 1.1 1.2
chandler/repository/packs/schema/model/items/Monitors.item None 1.1
chandler/repository/persistence/FileRepository.py 1.28 1.29
chandler/repository/persistence/XMLLob.py 1.1 1.2
chandler/repository/persistence/XMLRefDict.py 1.2 1.3
chandler/repository/persistence/XMLRepositoryView.py 1.46 1.47
chandler/repository/schema/Cloud.py 1.13 1.14
chandler/repository/schema/Kind.py 1.81 1.82
chandler/repository/schema/Types.py 1.67 1.68
chandler/repository/tests/TestBZ2.py 1.2 1.3
chandler/repository/tests/TestText.py 1.16 1.17
Log message:
- reworked all dirtying code so that it is called only once per change
- implemented attribute value monitors
- finished implementation of attribute value monitors for sorted indexes
- fixed bug in Kind.getInitialValues() with PersistentCollection values
- fixed bug in RefDict._removeRef with removing key from indexes
- renamed RefDict.removeItem() to remove()
ViewCVS links:
http://cvs.osafoundation.org/index.cgi/chandler/application/Application.py.diff?r1=text&tr1=1.259&r2=text&tr2=1.260
http://cvs.osafoundation.org/index.cgi/chandler/application/Parcel.py.diff?r1=text&tr1=1.26&r2=text&tr2=1.27
http://cvs.osafoundation.org/index.cgi/chandler/parcels/osaf/framework/blocks/ContainerBlocks.py.diff?r1=text&tr1=1.124&r2=text&tr2=1.125
http://cvs.osafoundation.org/index.cgi/chandler/parcels/osaf/framework/blocks/calendar/CalendarBlocks.py.diff?r1=text&tr1=1.27&r2=text&tr2=1.28
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/Monitors.py?rev=1.1&content-type=text/vnd.viewcvs-markup
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/Indexes.py.diff?r1=text&tr1=1.3&r2=text&tr2=1.4
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/Item.py.diff?r1=text&tr1=1.151&r2=text&tr2=1.152
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/ItemHandler.py.diff?r1=text&tr1=1.43&r2=text&tr2=1.44
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/ItemRef.py.diff?r1=text&tr1=1.86&r2=text&tr2=1.87
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/PersistentCollections.py.diff?r1=text&tr1=1.18&r2=text&tr2=1.19
http://cvs.osafoundation.org/index.cgi/chandler/repository/item/Values.py.diff?r1=text&tr1=1.13&r2=text&tr2=1.14
http://cvs.osafoundation.org/index.cgi/chandler/repository/packs/schema.pack.diff?r1=text&tr1=1.19&r2=text&tr2=1.20
http://cvs.osafoundation.org/index.cgi/chandler/repository/packs/schema/model/Items.namespace?rev=1.1&content-type=text/vnd.viewcvs-markup
http://cvs.osafoundation.org/index.cgi/chandler/repository/packs/schema/model/Monitors.kind?rev=1.1&content-type=text/vnd.viewcvs-markup
http://cvs.osafoundation.org/index.cgi/chandler/repository/packs/schema/model/Item.kind.diff?r1=text&tr1=1.14&r2=text&tr2=1.15
http://cvs.osafoundation.org/index.cgi/chandler/repository/packs/schema/model/clouds/Item.cloud.diff?r1=text&tr1=1.1&r2=text&tr2=1.2
http://cvs.osafoundation.org/index.cgi/chandler/repository/packs/schema/model/items/Monitors.item?rev=1.1&content-type=text/vnd.viewcvs-markup
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/FileRepository.py.diff?r1=text&tr1=1.28&r2=text&tr2=1.29
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/XMLLob.py.diff?r1=text&tr1=1.1&r2=text&tr2=1.2
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/XMLRefDict.py.diff?r1=text&tr1=1.2&r2=text&tr2=1.3
http://cvs.osafoundation.org/index.cgi/chandler/repository/persistence/XMLRepositoryView.py.diff?r1=text&tr1=1.46&r2=text&tr2=1.47
http://cvs.osafoundation.org/index.cgi/chandler/repository/schema/Cloud.py.diff?r1=text&tr1=1.13&r2=text&tr2=1.14
http://cvs.osafoundation.org/index.cgi/chandler/repository/schema/Kind.py.diff?r1=text&tr1=1.81&r2=text&tr2=1.82
http://cvs.osafoundation.org/index.cgi/chandler/repository/schema/Types.py.diff?r1=text&tr1=1.67&r2=text&tr2=1.68
http://cvs.osafoundation.org/index.cgi/chandler/repository/tests/TestBZ2.py.diff?r1=text&tr1=1.2&r2=text&tr2=1.3
http://cvs.osafoundation.org/index.cgi/chandler/repository/tests/TestText.py.diff?r1=text&tr1=1.16&r2=text&tr2=1.17
Index: chandler/application/Parcel.py
diff -u chandler/application/Parcel.py:1.26 chandler/application/Parcel.py:1.27
--- chandler/application/Parcel.py:1.26 Fri Aug 13 08:31:43 2004
+++ chandler/application/Parcel.py Thu Aug 19 11:06:23 2004
@@ -1559,14 +1559,14 @@
elif card == "list":
# First, see if this is a ref collection, since we handle those
# differently; to remove an item from a ref collection, we use
- # removeItem( ) which takes an item parameter -- therefore we
+ # remove() which takes an item parameter -- therefore we
# first need to findUUID() the item.
if self.item.getAttributeAspect(attrName, "otherName"):
attr = self.item.getAttributeValue(attrName)
# value is a UUID -- let's load the associated item and then
# remove it from this collection
otherItem = self.item.findUUID(value)
- attr.removeItem(otherItem)
+ attr.remove(otherItem)
print "Reload: item %s, unassigning %s = '%s'" % \
(self.item.itsPath, attrName, otherItem.itsPath)
continue
Index: chandler/repository/persistence/XMLRefDict.py
diff -u chandler/repository/persistence/XMLRefDict.py:1.2 chandler/repository/persistence/XMLRefDict.py:1.3
--- chandler/repository/persistence/XMLRefDict.py:1.2 Wed Jul 28 08:38:07 2004
+++ chandler/repository/persistence/XMLRefDict.py Thu Aug 19 11:06:29 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.2 $"
-__date__ = "$Date: 2004/07/28 15:38:07 $"
+__revision__ = "$Revision: 1.3 $"
+__date__ = "$Date: 2004/08/19 18:06:29 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -45,9 +45,9 @@
return self._getRefs().loadRef(self._key, self._item._version, key)
- def _changeRef(self, key, alias=None):
+ def _changeRef(self, key, alias=None, noMonitors=False):
- super(XMLRefDict, self)._changeRef(key, alias)
+ super(XMLRefDict, self)._changeRef(key, alias, noMonitors)
if not self.view.isLoading():
self._changedRefs[key] = (0, alias)
Index: chandler/repository/persistence/FileRepository.py
diff -u chandler/repository/persistence/FileRepository.py:1.28 chandler/repository/persistence/FileRepository.py:1.29
--- chandler/repository/persistence/FileRepository.py:1.28 Mon Jun 7 23:59:08 2004
+++ chandler/repository/persistence/FileRepository.py Thu Aug 19 11:06:29 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.28 $"
-__date__ = "$Date: 2004/06/08 06:59:08 $"
+__revision__ = "$Revision: 1.29 $"
+__date__ = "$Date: 2004/08/19 18:06:29 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -155,7 +155,7 @@
if item.isDirty():
view._saveItem(item, **args)
count += 1
- item.setDirty(0)
+ item.setDirty(0, None)
contents.write(item.itsUUID.str16())
contents.write('\n')
Index: chandler/repository/tests/TestText.py
diff -u chandler/repository/tests/TestText.py:1.16 chandler/repository/tests/TestText.py:1.17
--- chandler/repository/tests/TestText.py:1.16 Fri Jul 16 08:04:53 2004
+++ chandler/repository/tests/TestText.py Thu Aug 19 11:06:31 2004
@@ -2,8 +2,8 @@
Text storage unit tests
"""
-__revision__ = "$Revision: 1.16 $"
-__date__ = "$Date: 2004/07/16 15:04:53 $"
+__revision__ = "$Revision: 1.17 $"
+__date__ = "$Date: 2004/08/19 18:06:31 $"
__copyright__ = "Copyright (c) 2003 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -46,7 +46,6 @@
input.close()
writer.close()
- movie.setDirty()
self.rep.logger.info("%s compressed %d bytes to %d",
compression, count, len(movie.synopsis._data))
@@ -93,7 +92,6 @@
data = input.read(548576)
if len(data) > 0:
writer.write(data)
- movie.setDirty()
writer.close()
self.rep.commit()
writer = movie.synopsis.getWriter(compression=compression,
Index: chandler/repository/packs/schema/model/Item.kind
diff -u chandler/repository/packs/schema/model/Item.kind:1.14 chandler/repository/packs/schema/model/Item.kind:1.15
--- chandler/repository/packs/schema/model/Item.kind:1.14 Thu Aug 5 06:57:37 2004
+++ chandler/repository/packs/schema/model/Item.kind Thu Aug 19 11:06:27 2004
@@ -25,4 +25,19 @@
</attribute>
</item>
+ <item withSchema="True">
+ <name>monitors</name>
+ <kind type="path">//Schema/Core/Attribute</kind>
+ <class module="repository.schema.Attribute">Attribute</class>
+ <parent type="path">//Schema/Core/Item</parent>
+
+ <ref name="kinds" otherName="attributes"
+ cardinality="list" otherCard="list">
+ <ref type="path">..</ref>
+ </ref>
+
+ <attribute name="cardinality">single</attribute>
+ <attribute name="otherName">items</attribute>
+ </item>
+
</items>
Index: chandler/repository/packs/schema/model/clouds/Item.cloud
diff -u chandler/repository/packs/schema/model/clouds/Item.cloud:1.1 chandler/repository/packs/schema/model/clouds/Item.cloud:1.2
--- chandler/repository/packs/schema/model/clouds/Item.cloud:1.1 Mon Aug 16 09:38:37 2004
+++ chandler/repository/packs/schema/model/clouds/Item.cloud Thu Aug 19 11:06:28 2004
@@ -14,5 +14,4 @@
type="path">//Schema/Core/Item</ref>
</item>
-
</items>
Index: chandler/repository/schema/Kind.py
diff -u chandler/repository/schema/Kind.py:1.81 chandler/repository/schema/Kind.py:1.82
--- chandler/repository/schema/Kind.py:1.81 Thu Aug 5 06:57:38 2004
+++ chandler/repository/schema/Kind.py Thu Aug 19 11:06:30 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.81 $"
-__date__ = "$Date: 2004/08/05 13:57:38 $"
+__revision__ = "$Revision: 1.82 $"
+__date__ = "$Date: 2004/08/19 18:06:30 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -343,7 +343,7 @@
if name not in values:
if isinstance(value, PersistentCollection):
value = value._copy(item, name, value._companion,
- {}, 'copy')
+ 'copy', lambda x, other, z: other)
elif isinstance(value, ItemValue):
value = value._copy(item, name)
Index: chandler/repository/persistence/XMLLob.py
diff -u chandler/repository/persistence/XMLLob.py:1.1 chandler/repository/persistence/XMLLob.py:1.2
--- chandler/repository/persistence/XMLLob.py:1.1 Wed Jul 21 14:32:29 2004
+++ chandler/repository/persistence/XMLLob.py Thu Aug 19 11:06:29 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.1 $"
-__date__ = "$Date: 2004/07/21 21:32:29 $"
+__revision__ = "$Revision: 1.2 $"
+__date__ = "$Date: 2004/08/19 18:06:29 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -81,7 +81,6 @@
if self._uuid is None:
self._uuid = UUID()
- self._setDirty()
return self._uuid
@@ -210,7 +209,6 @@
if self._uuid is None:
self._uuid = UUID()
- self._setDirty()
return self._uuid
Index: chandler/parcels/osaf/framework/blocks/ContainerBlocks.py
diff -u chandler/parcels/osaf/framework/blocks/ContainerBlocks.py:1.124 chandler/parcels/osaf/framework/blocks/ContainerBlocks.py:1.125
--- chandler/parcels/osaf/framework/blocks/ContainerBlocks.py:1.124 Wed Aug 11 06:33:13 2004
+++ chandler/parcels/osaf/framework/blocks/ContainerBlocks.py Thu Aug 19 11:06:24 2004
@@ -1,5 +1,5 @@
-__version__ = "$Revision: 1.124 $"
-__date__ = "$Date: 2004/08/11 13:33:13 $"
+__version__ = "$Revision: 1.125 $"
+__date__ = "$Date: 2004/08/19 18:06:24 $"
__copyright__ = "Copyright (c) 2003 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -183,7 +183,7 @@
newSize = self.GetSize()
self.blockItem.size.width = newSize.width
self.blockItem.size.height = newSize.height
- self.blockItem.setDirty() # Temporary repository hack -- DJA
+ self.blockItem.setDirty(self.blockItem.VDIRTY, 'size') # Temporary repository hack -- DJA
if self.blockItem.orientationEnum == "Horizontal":
distance = self.blockItem.size.height
Index: chandler/repository/persistence/XMLRepositoryView.py
diff -u chandler/repository/persistence/XMLRepositoryView.py:1.46 chandler/repository/persistence/XMLRepositoryView.py:1.47
--- chandler/repository/persistence/XMLRepositoryView.py:1.46 Tue Jul 27 12:46:45 2004
+++ chandler/repository/persistence/XMLRepositoryView.py Thu Aug 19 11:06:29 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.46 $"
-__date__ = "$Date: 2004/07/27 19:46:45 $"
+__revision__ = "$Revision: 1.47 $"
+__date__ = "$Date: 2004/08/19 18:06:29 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -60,7 +60,7 @@
del self._deletedRegistry[item.itsUUID]
item._status &= ~Item.DELETED
else:
- item.setDirty(0)
+ item.setDirty(0, None)
item._unloadItem()
for item in self._log:
Index: chandler/parcels/osaf/framework/blocks/calendar/CalendarBlocks.py
diff -u chandler/parcels/osaf/framework/blocks/calendar/CalendarBlocks.py:1.27 chandler/parcels/osaf/framework/blocks/calendar/CalendarBlocks.py:1.28
--- chandler/parcels/osaf/framework/blocks/calendar/CalendarBlocks.py:1.27 Tue Aug 3 17:40:35 2004
+++ chandler/parcels/osaf/framework/blocks/calendar/CalendarBlocks.py Thu Aug 19 11:06:24 2004
@@ -1,8 +1,8 @@
""" Calendar Blocks
"""
-__version__ = "$Revision: 1.27 $"
-__date__ = "$Date: 2004/08/04 00:40:35 $"
+__version__ = "$Revision: 1.28 $"
+__date__ = "$Date: 2004/08/19 18:06:24 $"
__copyright__ = "Copyright (c) 2003 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -234,7 +234,7 @@
newSize = self.GetSize()
self.blockItem.size.width = newSize.width
self.blockItem.size.height = newSize.height
- self.blockItem.setDirty() # Temporary repository hack -- DJA
+ self.blockItem.setDirty(self.blockItem.VDIRTY, 'size') # Temporary repository hack -- DJA
self.SetVirtualSize(newSize)
self.displayItems()
self._positionNavigationButtons()
Index: chandler/repository/tests/TestBZ2.py
diff -u chandler/repository/tests/TestBZ2.py:1.2 chandler/repository/tests/TestBZ2.py:1.3
--- chandler/repository/tests/TestBZ2.py:1.2 Sun May 30 12:29:00 2004
+++ chandler/repository/tests/TestBZ2.py Thu Aug 19 11:06:31 2004
@@ -2,8 +2,8 @@
Text blocked read of appended storage compression unit tests
"""
-__revision__ = "$Revision: 1.2 $"
-__date__ = "$Date: 2004/05/30 19:29:00 $"
+__revision__ = "$Revision: 1.3 $"
+__date__ = "$Date: 2004/08/19 18:06:31 $"
__copyright__ = "Copyright (c) 2003 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -43,7 +43,6 @@
data = input.read(54857)
if len(data) > 0:
writer.write(data)
- movie.setDirty()
writer.close()
self.rep.commit()
writer = movie.synopsis.getWriter(compression=compression,
Index: chandler/repository/schema/Cloud.py
diff -u chandler/repository/schema/Cloud.py:1.13 chandler/repository/schema/Cloud.py:1.14
--- chandler/repository/schema/Cloud.py:1.13 Thu Aug 5 06:57:38 2004
+++ chandler/repository/schema/Cloud.py Thu Aug 19 11:06:30 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.13 $"
-__date__ = "$Date: 2004/08/05 13:57:38 $"
+__revision__ = "$Revision: 1.14 $"
+__date__ = "$Date: 2004/08/19 18:06:30 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -317,9 +317,8 @@
method = self.getAttributeValue('method', default=None,
_attrDict=self._values)
if method is not None:
- results.extend(getattr(type(item), method)(item, items,
- references,
- cloudAlias))
+ results.extend(getattr(item, method)(items, references,
+ cloudAlias))
else:
raise NotImplementedError, policy
Index: chandler/application/Application.py
diff -u chandler/application/Application.py:1.259 chandler/application/Application.py:1.260
--- chandler/application/Application.py:1.259 Sat Aug 14 17:03:05 2004
+++ chandler/application/Application.py Thu Aug 19 11:06:23 2004
@@ -1,5 +1,5 @@
-__version__ = "$Revision: 1.259 $"
-__date__ = "$Date: 2004/08/15 00:03:05 $"
+__version__ = "$Revision: 1.260 $"
+__date__ = "$Date: 2004/08/19 18:06:23 $"
__copyright__ = "Copyright (c) 2003-2004 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -107,7 +107,7 @@
if not Globals.wxApplication.ignoreSynchronizeWidget:
Globals.mainView.size.width = self.GetSize().x
Globals.mainView.size.height = self.GetSize().y
- Globals.mainView.setDirty() # Temporary repository hack -- DJA
+ Globals.mainView.setDirty(Globals.mainView.VDIRTY, 'size') # Temporary repository hack -- DJA
event.Skip()
Index: chandler/repository/schema/Types.py
diff -u chandler/repository/schema/Types.py:1.67 chandler/repository/schema/Types.py:1.68
--- chandler/repository/schema/Types.py:1.67 Wed Jul 28 13:40:39 2004
+++ chandler/repository/schema/Types.py Thu Aug 19 11:06:30 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.67 $"
-__date__ = "$Date: 2004/07/28 20:40:39 $"
+__revision__ = "$Revision: 1.68 $"
+__date__ = "$Date: 2004/08/19 18:06:30 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -776,15 +776,17 @@
generator.startElement('values', {})
for key, val in value._iteritems():
ItemHandler.xmlValue(repository,
- key, val, 'value', None, 'single', None, 0,
+ key, val, 'value', None, 'single', None, {},
generator, withSchema)
generator.endElement('values')
def makeValue(self, data):
- """Make a dict of string key/value pairs from comma separated pairs.
+ """
+ Make a dict of string key/value pairs from comma separated pairs.
The implementation is very cheap, using split, so spaces are part of
- the dict's elements and the strings cannot contain spaces or colons."""
+ the dict's elements and the strings cannot contain spaces or colons.
+ """
result = {}
if data:
@@ -820,15 +822,17 @@
generator.startElement('values', {})
for val in value._itervalues():
ItemHandler.xmlValue(repository,
- None, val, 'value', None, 'single', None, 0,
+ None, val, 'value', None, 'single', None, {},
generator, withSchema)
generator.endElement('values')
def makeValue(self, data):
- """Make a list of strings from comma separated strings.
+ """
+ Make a list of strings from comma separated strings.
The implementation is very cheap, using split, so spaces are part of
- the list's elements and the strings cannot contain spaces."""
+ the list's elements and the strings cannot contain spaces.
+ """
if data:
return data.split(',')
Index: chandler/repository/item/Indexes.py
diff -u chandler/repository/item/Indexes.py:1.3 chandler/repository/item/Indexes.py:1.4
--- chandler/repository/item/Indexes.py:1.3 Wed Jul 28 13:40:38 2004
+++ chandler/repository/item/Indexes.py Thu Aug 19 11:06:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.3 $"
-__date__ = "$Date: 2004/07/28 20:40:38 $"
+__revision__ = "$Revision: 1.4 $"
+__date__ = "$Date: 2004/08/19 18:06:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -168,14 +168,14 @@
def afterKey(self, key):
- pos = lo = 0;
- hi = len(self._index) - 1;
+ pos = lo = 0
+ hi = len(self._index) - 1
afterKey = None
while lo <= hi:
pos = (lo + hi) >> 1
afterKey = self.getKey(pos)
- diff = self.compare(key, afterKey);
+ diff = self.compare(key, afterKey)
if diff == 0:
return afterKey
@@ -184,7 +184,7 @@
hi = pos - 1
else:
pos += 1
- lo = pos;
+ lo = pos
if pos == 0:
return None
@@ -194,10 +194,14 @@
def insertKey(self, key, afterKey):
self._index.insertKey(key, self.afterKey(key))
+
+ def removeKey(self, key):
+
+ self._index.removeKey(key)
def moveKey(self, key, afterKey):
- self.removeKey(key)
+ self._index.removeKey(key)
self._index.insertKey(key, self.afterKey(key))
@@ -227,6 +231,16 @@
return 0
+ def insertKey(self, key, afterKey):
+
+ self._valueMap[key].addMonitor(self._attribute)
+ super(AttributeIndex, self).insertKey(key, afterKey)
+
+ def removeKey(self, key):
+
+ self._valueMap[key].removeMonitor(self._attribute)
+ super(AttributeIndex, self).removeKey(key)
+
def _xmlValues(self, generator, version, attrs, mode):
attrs['attribute'] = self._attribute
Index: chandler/repository/item/ItemHandler.py
diff -u chandler/repository/item/ItemHandler.py:1.43 chandler/repository/item/ItemHandler.py:1.44
--- chandler/repository/item/ItemHandler.py:1.43 Tue Jul 27 10:46:19 2004
+++ chandler/repository/item/ItemHandler.py Thu Aug 19 11:06:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.43 $"
-__date__ = "$Date: 2004/07/27 17:46:19 $"
+__revision__ = "$Revision: 1.44 $"
+__date__ = "$Date: 2004/08/19 18:06:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -105,11 +105,15 @@
flags = attrs.get('flags', None)
if flags is not None:
flags = int(flags)
- self.values._setFlags(name, flags)
+ self.references._setFlags(name, flags)
readOnly = flags & Values.READONLY
else:
readOnly = False
+ monitors = attrs.get('monitors', None)
+ if monitors is not None:
+ self.references._addMonitor(name, int(monitors))
+
cardinality = self.getCardinality(attribute, attrs)
if cardinality != 'single':
@@ -420,6 +424,10 @@
elif isinstance(value, ItemValue):
value._setReadOnly()
+ monitors = attrs.get('monitors', None)
+ if monitors is not None:
+ self.values._addMonitor(attrs['name'], int(monitors))
+
def valueEnd(self, itemHandler, attrs, **kwds):
if kwds.has_key('value'):
@@ -444,10 +452,10 @@
name = attrs.get('name')
if name is None:
- self.collections[-1].append(value)
+ self.collections[-1].append(value, False)
else:
name = self.makeValue(attrs.get('nameType', 'str'), name)
- self.collections[-1][name] = value
+ self.collections[-1].__setitem__(name, value, False)
def getCardinality(self, attribute, attrs):
@@ -567,12 +575,9 @@
return cls.typeHandler(repository, value).makeString(value)
- def xmlValue(cls, repository, name, value, tag,
- attrType, attrCard, attrId, flags,
- generator, withSchema):
+ def xmlValue(cls, repository, name, value, tag, attrType, attrCard, attrId,
+ attrs, generator, withSchema):
- attrs = {}
-
if name is not None:
if not isinstance(name, str) and not isinstance(name, unicode):
attrs['nameType'] = cls.typeName(repository, name)
@@ -598,9 +603,6 @@
else:
attrs['cardinality'] = attrCard
- if flags:
- attrs['flags'] = str(flags)
-
generator.startElement(tag, attrs)
if attrCard == 'single':
@@ -622,13 +624,13 @@
for val in value._itervalues():
cls.xmlValue(repository,
None, val, 'value', attrType, 'single',
- None, 0, generator, withSchema)
+ None, {}, generator, withSchema)
elif attrCard == 'dict':
for key, val in value._iteritems():
cls.xmlValue(repository,
key, val, 'value', attrType, 'single',
- None, 0, generator, withSchema)
+ None, {}, generator, withSchema)
else:
raise ValueError, attrCard
Index: chandler/repository/item/Values.py
diff -u chandler/repository/item/Values.py:1.13 chandler/repository/item/Values.py:1.14
--- chandler/repository/item/Values.py:1.13 Sun Aug 1 04:14:40 2004
+++ chandler/repository/item/Values.py Thu Aug 19 11:06:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.13 $"
-__date__ = "$Date: 2004/08/01 11:14:40 $"
+__revision__ = "$Revision: 1.14 $"
+__date__ = "$Date: 2004/08/19 18:06:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -53,9 +53,6 @@
if self._getFlags(key) & Values.READONLY:
raise AttributeError, 'Value for %s on %s is read-only' %(key, self._item.itsPath)
- if self._item is not None:
- self._item.setDirty(attribute=key)
-
return super(Values, self).__setitem__(key, value)
def __delitem__(self, key):
@@ -63,9 +60,6 @@
if self._getFlags(key) & Values.READONLY:
raise AttributeError, 'Value for %s on %s is read-only' %(key, self._item.itsPath)
- if self._item is not None:
- self._item.setDirty(attribute=key)
-
return super(Values, self).__delitem__(key)
def _unload(self):
@@ -111,6 +105,36 @@
self._flags[key] &= ~Values.TRANSIENT
+ def _addMonitor(self, key, count=1):
+
+ if '_monitors' in self.__dict__:
+ self._monitors[key] += count
+ else:
+ self._monitors = { key: count }
+
+ def _hasMonitors(self, key):
+
+ return '_monitors' in self.__dict__ and key in self._monitors
+ #return True
+
+ def _removeMonitor(self, key):
+
+ monitors = self._getMonitors(key)
+
+ if monitors:
+ self._monitors[key] = monitors - 1
+ else:
+ raise AttributeError, 'no monitors on attribute %s' %(key)
+
+ def _getMonitors(self, key):
+
+ try:
+ return self._monitors[key]
+ except AttributeError:
+ return 0
+ except KeyError:
+ return 0
+
def _xmlValues(self, generator, withSchema, version, mode):
from repository.item.ItemHandler import ItemHandler
@@ -131,7 +155,8 @@
persist = True
if persist:
- persist = self._getFlags(key) & self.TRANSIENT == 0
+ flags = self._getFlags(key)
+ persist = flags & self.TRANSIENT == 0
if persist:
if attribute is not None:
@@ -144,15 +169,21 @@
attrCard = 'single'
attrId = None
+ monitors = self._getMonitors(key)
+ attrs = {}
+ if flags:
+ attrs['flags'] = str(flags)
+ if monitors:
+ attrs['monitors'] = str(monitors)
+
try:
ItemHandler.xmlValue(repository, key, value, 'attribute',
- attrType, attrCard, attrId,
- self._getFlags(key), generator,
- withSchema)
+ attrType, attrCard, attrId, attrs,
+ generator, withSchema)
except Exception, e:
e.args = ("while saving attribute '%s' of item %s, %s" %(key, item.itsPath, e.args[0]),)
raise
-
+
READONLY = 0x0001 # value is read-only
TRANSIENT = 0x0002 # value is transient
@@ -180,10 +211,6 @@
policy = copyPolicy or item.getAttributeAspect(name, 'copyPolicy')
value._copy(self, orig._item, item, name, policy, copyFn)
- def __setitem__(self, key, value, *args):
-
- super(References, self).__setitem__(key, value)
-
def _unload(self):
for value in self.itervalues():
@@ -195,8 +222,19 @@
for key, value in self.iteritems():
if item.getAttributeAspect(key, 'persist', default=True):
+ flags = self._getFlags(key)
+ monitors = self._getMonitors(key)
+ attrs = {}
+ if flags:
+ attrs['flags'] = str(flags)
+ if monitors:
+ attrs['monitors'] = str(monitors)
value._xmlValue(key, item, generator, withSchema, version,
- self._getFlags(key), mode)
+ attrs, mode)
+
+ def _isRefDict(self):
+
+ return False
class ItemValue(object):
@@ -215,9 +253,6 @@
raise ValueError, 'item attribute value %s is already owned by another item %s' %(self, self._item)
self._item = item
- if self._dirty:
- item.setDirty()
-
self._attribute = attribute
def _setReadOnly(self, readOnly=True):
@@ -241,11 +276,10 @@
if self._isReadOnly():
raise AttributeError, 'Value for %s on %s is read-only' %(self._attribute, self._item.itsPath)
- if not self._dirty:
- self._dirty = True
- item = self._item
- if item is not None:
- item.setDirty(attribute=self._attribute, dirty=item.VDIRTY)
+ self._dirty = True
+ item = self._item
+ if item is not None:
+ item.setDirty(item.VDIRTY, self._attribute, item._values)
def _copy(self, item, attribute):
Index: chandler/repository/packs/schema.pack
diff -u chandler/repository/packs/schema.pack:1.19 chandler/repository/packs/schema.pack:1.20
--- chandler/repository/packs/schema.pack:1.19 Mon Aug 16 09:38:37 2004
+++ chandler/repository/packs/schema.pack Thu Aug 19 11:06:27 2004
@@ -23,6 +23,7 @@
<item file="Cloud.kind" />
<item file="Endpoint.kind" />
<item file="Principal.kind" />
+ <item file="Monitors.kind" />
<item file="Clouds.namespace" cwd="clouds">
<item file="Kind.cloud" />
@@ -31,6 +32,10 @@
</item>
<item file="Mixins.namespace" />
+
+ <item file="Items.namespace" cwd="items">
+ <item file="Monitors.item" />
+ </item>
</item>
</item>
Index: chandler/repository/item/Item.py
diff -u chandler/repository/item/Item.py:1.151 chandler/repository/item/Item.py:1.152
--- chandler/repository/item/Item.py:1.151 Thu Aug 5 06:57:37 2004
+++ chandler/repository/item/Item.py Thu Aug 19 11:06:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.151 $"
-__date__ = "$Date: 2004/08/05 13:57:37 $"
+__revision__ = "$Revision: 1.152 $"
+__date__ = "$Date: 2004/08/19 18:06:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -310,7 +310,7 @@
return kwds.get('default', None)
def setAttributeValue(self, name, value=None, setAliases=False,
- _attrDict=None):
+ _attrDict=None, setDirty=True):
"""
Set a value on a Chandler attribute.
@@ -366,7 +366,8 @@
if old is not NoneRef:
# reattaching on original endpoint
old.reattach(self, name, old.other(self), value,
- self._kind.getOtherName(name))
+ self._kind.getOtherName(name),
+ setDirty=setDirty)
return value
elif isRef:
# reattaching on other endpoint,
@@ -382,8 +383,6 @@
else:
raise TypeError, type(old)
- self.setDirty(attribute=name)
-
if isItem:
otherName = self._kind.getOtherName(name, default=None)
card = self.getAttributeAspect(name, 'cardinality',
@@ -394,13 +393,16 @@
if otherName is None:
self._values[name] = value = SingleRef(value.itsUUID)
-
+
else:
value = ItemRef(self, name, value, otherName)
self._references[name] = value
+ dirty = Item.VDIRTY
+
elif isRef:
self._references[name] = value
+ dirty = Item.VDIRTY
elif isinstance(value, list):
if _attrDict is self._references:
@@ -409,13 +411,17 @@
else:
assert isinstance(old, RefDict)
refDict = old
+
refDict.extend(value)
value = refDict
+ setDirty = False
else:
companion = self.getAttributeAspect(name, 'companion',
default=None)
- value = PersistentList(self, name, companion, value)
- self._values[name] = value
+ attrValue = PersistentList(self, name, companion)
+ self._values[name] = attrValue
+ attrValue.extend(value)
+ setDirty = False
elif isinstance(value, dict):
if _attrDict is self._references:
@@ -424,23 +430,96 @@
else:
assert isinstance(old, RefDict)
refDict = old
+
refDict.update(value, setAliases)
value = refDict
+ setDirty = False
else:
companion = self.getAttributeAspect(name, 'companion',
default=None)
- value = PersistentDict(self, name, companion, value)
- self._values[name] = value
+ attrValue = PersistentDict(self, name, companion)
+ self._values[name] = attrValue
+ attrValue.update(value)
+ setDirty = False
elif isinstance(value, ItemValue):
value._setItem(self, name)
self._values[name] = value
+ dirty = Item.VDIRTY
else:
self._values[name] = value
+ dirty = Item.VDIRTY
+ if setDirty:
+ self.setDirty(dirty, name, _attrDict)
+
return value
+ def _invokeMonitors(self, name, attrDict):
+
+ if attrDict._hasMonitors(name):
+ from repository.item.Monitors import Monitors
+ Monitors.invoke('set', self, name)
+
+ def _reIndex(self, op, item, attrName, collectionName, indexName):
+
+ if op == 'set':
+ refDict = self.getAttributeValue(collectionName, default=None,
+ _attrDict=self._references)
+ if refDict is not None and item._uuid in refDict:
+ refDict.placeItem(item, None, indexName)
+
+ def addMonitor(self, name, _attrDict=None):
+
+ if _attrDict is None:
+ if self._values.has_key(name):
+ _attrDict = self._values
+ elif self._references.has_key(name):
+ _attrDict = self._references
+ elif self._kind.getOtherName(name, default=None) is not None:
+ _attrDict = self._references
+ else:
+ redirect = self.getAttributeAspect(name, 'redirectTo',
+ default=None)
+ if redirect is not None:
+ item = self
+ names = redirect.split('.')
+ for i in xrange(len(names) - 1):
+ item = item.getAttributeValue(names[i])
+
+ return item.addMonitor(name)
+
+ else:
+ _attrDict = self._values
+
+ _attrDict._addMonitor(name)
+
+ def removeMonitor(self, name, _attrDict=None):
+
+ if _attrDict is None:
+ if self._values.has_key(name):
+ _attrDict = self._values
+ elif self._references.has_key(name):
+ _attrDict = self._references
+ elif self._kind.getOtherName(name, default=None) is not None:
+ _attrDict = self._references
+ else:
+ redirect = self.getAttributeAspect(name, 'redirectTo',
+ default=None)
+ if redirect is not None:
+ item = self
+ names = redirect.split('.')
+ for i in xrange(len(names) - 1):
+ item = item.getAttributeValue(names[i])
+
+ return item.removeMonitor(name)
+
+ else:
+ _attrDict = self._values
+
+ _attrDict._removeMonitor(name)
+
def getAttributeValue(self, name, _attrDict=None, **kwds):
"""
Return a Chandler attribute value.
@@ -545,8 +624,6 @@
@return: C{None}
"""
- self.setDirty(attribute=name)
-
if _attrDict is None:
if self._values.has_key(name):
_attrDict = self._values
@@ -555,6 +632,7 @@
if _attrDict is self._values:
del _attrDict[name]
+ dirty = Item.VDIRTY
elif _attrDict is self._references:
value = _attrDict[name]
@@ -562,12 +640,17 @@
value.detach(self, name,
value.other(self), self._kind.getOtherName(name))
del _attrDict[name]
+ dirty = Item.VDIRTY
elif isinstance(value, RefDict):
value.clear()
del _attrDict[name]
+ dirty = None
else:
raise TypeError, (type(value), value)
+ if dirty is not None:
+ self.setDirty(dirty, name)
+
def hasChild(self, name, load=True):
"""
Tell whether this item has a child of that name.
@@ -878,8 +961,6 @@
isItem = isinstance(value, Item)
attrValue = _attrDict.get(attribute, Item.Nil)
- self.setDirty(attribute=attribute)
-
if attrValue is Item.Nil:
card = self.getAttributeAspect(attribute, 'cardinality',
default='single')
@@ -894,8 +975,9 @@
companion = self.getAttributeAspect(attribute, 'companion',
default=None)
attrValue = PersistentDict(self, attribute, companion)
- attrValue[key] = value
_attrDict[attribute] = attrValue
+ attrValue[key] = value
+
return attrValue
elif card == 'list':
@@ -908,8 +990,9 @@
companion = self.getAttributeAspect(attribute, 'companion',
default=None)
attrValue = PersistentList(self, attribute, companion)
- attrValue.append(value)
_attrDict[attribute] = attrValue
+ attrValue.append(value)
+
return attrValue
else:
@@ -978,22 +1061,19 @@
if attrValue is Item.Nil:
return self.setValue(attribute, value, key, alias, _attrDict)
- else:
- self.setDirty(attribute=attribute)
-
- if isinstance(attrValue, RefDict):
- if isinstance(value, Item):
- attrValue.append(value, alias)
- else:
- raise TypeError, type(value)
- elif isinstance(attrValue, dict):
- attrValue[key] = value
- elif isinstance(attrValue, list):
- attrValue.append(value)
+ elif isinstance(attrValue, RefDict):
+ if isinstance(value, Item):
+ attrValue.append(value, alias)
else:
- return self.setAttributeValue(attribute, value, _attrDict)
+ raise TypeError, type(value)
+ elif isinstance(attrValue, dict):
+ attrValue[key] = value
+ elif isinstance(attrValue, list):
+ attrValue.append(value)
+ else:
+ return self.setAttributeValue(attribute, value, _attrDict)
- return attrValue
+ return attrValue
def hasKey(self, attribute, key=None, alias=None, _attrDict=None):
"""
@@ -1118,8 +1198,6 @@
else:
raise KeyError, 'No value for attribute %s' %(attribute)
- self.setDirty(attribute=attribute)
-
def _removeRef(self, name):
del self._references[name]
@@ -1245,16 +1323,16 @@
return self._status & Item.DIRTY
- def setDirty(self, dirty=None, attribute=None):
+ def setDirty(self, dirty, attribute, attrDict=None):
"""
Mark this item to get committed with the current transaction.
Returns C{True} if the dirty bit was changed from unset to set.
Returns C{False} otherwise.
- If C{attribute} is used and denotes a transient attribute (whose
- C{persist} aspect is C{False}), then this method has no effect and
- returns C{False}.
+ If C{attribute} denotes a transient attribute (whose C{persist}
+ aspect is C{False}), then this method has no effect and returns
+ C{False}.
@param dirty: one of L{Item.VDIRTY <VDIRTY>},
L{Item.RDIRTY <RDIRTY>}, L{Item.CDIRTY <CDIRTY>},
@@ -1268,8 +1346,13 @@
@return: C{True} or C{False}
"""
- if dirty is None:
- dirty = Item.VDIRTY
+ if self._status & Item.NODIRTY:
+ return False
+
+ if attrDict is not None:
+ assert attribute is not None
+ assert attrDict is not None
+ self._invokeMonitors(attribute, attrDict)
if dirty:
self._lastAccess = Item._countAccess()
@@ -1367,9 +1450,13 @@
if copyFn is None:
copyFn = copyOther
+
+ item._status |= Item.NODIRTY
item._values._copy(self._values, copyPolicy, copyFn)
item._references._copy(self._references, copyPolicy, copyFn)
-
+ item._status &= ~Item.NODIRTY
+ item.setDirty(Item.DIRTY, None)
+
if hasattr(cls, 'onItemCopy'):
item.onItemCopy(self)
@@ -1399,7 +1486,7 @@
if not recursive and self.hasChildren():
raise ValueError, 'item %s has children, delete must be recursive' %(self)
- self.setDirty()
+ self.setDirty(Item.DIRTY, None)
self._status |= Item.DELETING
others = []
@@ -1525,7 +1612,7 @@
if newRepository is not None:
newRepository._registerItem(self)
- self.setDirty()
+ self.setDirty(Item.CDIRTY, None)
for child in self.iterChildren(load=False):
child._setRoot(root)
@@ -1549,7 +1636,7 @@
def __setKind(self, kind):
if kind is not self._kind:
- self.setDirty()
+ self.setDirty(Item.DIRTY, None)
if self._kind is not None:
if kind is None:
@@ -1749,7 +1836,7 @@
parent._removeItem(self)
self._name = name or self._uuid.str64()
parent._addItem(self)
- self.setDirty(dirty=Item.SDIRTY)
+ self.setDirty(Item.SDIRTY, None)
if not '_origName' in self.__dict__:
self.__dict__['_origName'] = (parent.itsUUID, origName)
@@ -2304,9 +2391,10 @@
SAVED = 0x1000
ADIRTY = 0x2000 # acl(s) changed
PINNED = 0x4000 # auto-refresh, don't stale
-
+ NODIRTY = 0x8000 # turn off dirtying
+
VRDIRTY = VDIRTY | RDIRTY
- DIRTY = VDIRTY | SDIRTY | CDIRTY | RDIRTY | ADIRTY
+ DIRTY = VDIRTY | SDIRTY | CDIRTY | RDIRTY
__access__ = 0L
@@ -2408,9 +2496,9 @@
def linkChanged(self, link, key):
if key is None:
- self._item.setDirty(dirty=Item.CDIRTY)
+ self._item.setDirty(Item.CDIRTY, None)
else:
- link._value.setDirty(dirty=Item.SDIRTY)
+ link._value.setDirty(Item.SDIRTY, None)
def __repr__(self):
Index: chandler/repository/item/PersistentCollections.py
diff -u chandler/repository/item/PersistentCollections.py:1.18 chandler/repository/item/PersistentCollections.py:1.19
--- chandler/repository/item/PersistentCollections.py:1.18 Sun Aug 1 04:14:40 2004
+++ chandler/repository/item/PersistentCollections.py Thu Aug 19 11:06:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.18 $"
-__date__ = "$Date: 2004/08/01 11:14:40 $"
+__revision__ = "$Revision: 1.19 $"
+__date__ = "$Date: 2004/08/19 18:06:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -60,20 +60,25 @@
if self._readOnly:
raise ReadOnlyError, 'collection is read-only'
- if self._item:
- self._item.setDirty()
+ item = self._item
+ if item is not None:
+ item.setDirty(item.VDIRTY, self._attribute, item._values)
- def _prepareValue(self, value):
+ def _prepareValue(self, value, setDirty=True):
if isinstance(value, PersistentCollection):
value = value._copy(self._item, self._attribute, self._companion,
'copy', lambda x, other, z: other)
elif isinstance(value, list):
- value = PersistentList(self._item, self._attribute,
- self._companion, value)
+ persistentValue = PersistentList(self._item, self._attribute,
+ self._companion)
+ persistentValue.extend(value, setDirty)
+ value = persistentValue
elif isinstance(value, dict):
- value = PersistentDict(self._item, self._attribute,
- self._companion, value)
+ persistentValue = PersistentDict(self._item, self._attribute,
+ self._companion)
+ persistentValue.update(value, setDirty)
+ value = persistentValue
elif isinstance(value, repository.item.Item.Item):
value = SingleRef(value._uuid)
elif isinstance(value, repository.item.Values.ItemValue):
@@ -123,14 +128,11 @@
class PersistentList(list, PersistentCollection):
'A persistence aware list, tracking changes into a dirty bit.'
- def __init__(self, item, attribute, companion, initialValues=None):
+ def __init__(self, item, attribute, companion):
list.__init__(self)
PersistentCollection.__init__(self, item, attribute, companion)
- if initialValues is not None:
- self.extend(initialValues)
-
def _copy(self, item, attribute, companion, copyPolicy, copyFn):
copy = type(self)(item, attribute, companion)
@@ -141,12 +143,12 @@
if isinstance(value, repository.item.Item.Item):
value = copyFn(item, value, policy)
if value is not None:
- copy.append(value)
+ copy.append(value, False)
elif isinstance(value, PersistentCollection):
copy.append(value._copy(item, attribute, companion,
- copyPolicy, copyFn))
+ copyPolicy, copyFn), False)
else:
- copy.append(value)
+ copy.append(value, False)
return copy
@@ -154,86 +156,87 @@
self._storeValue(value)
value = self._prepareValue(value)
- self._setDirty()
super(PersistentList, self).__setitem__(index, value)
+ self._setDirty()
def __delitem__(self, index):
- self._setDirty()
super(PersistentList, self).__delitem__(index)
+ self._setDirty()
def __setslice__(self, start, end, value):
for v in value:
self._storeValue(v)
value = [self._prepareValue(v) for v in value]
- self._setDirty()
super(PersistentList, self).__setslice__(start, end, value)
+ self._setDirty()
def __delslice__(self, start, end):
- self._setDirty()
super(PersistentList, self).__delslice__(start, end)
+ self._setDirty()
def __iadd__(self, value):
for v in value:
self._storeValue(v)
value = [self._prepareValue(v) for v in value]
- self._setDirty()
super(PersistentList, self).__iadd__(value)
+ self._setDirty()
def __imul__(self, value):
- self._setDirty()
super(PersistentList, self).__imul__(value)
+ self._setDirty()
- def append(self, value):
+ def append(self, value, setDirty=True):
self._storeValue(value)
value = self._prepareValue(value)
- self._setDirty()
super(PersistentList, self).append(value)
+ if setDirty:
+ self._setDirty()
+
def insert(self, index, value):
self._storeValue(value)
value = self._prepareValue(value)
- self._setDirty()
super(PersistentList, self).insert(index, value)
+ self._setDirty()
- def pop(self, index = -1):
+ def pop(self, index=-1):
- self._setDirty()
value = super(PersistentList, self).pop(index)
value = self._restoreValue(value)
+ self._setDirty()
return value
def remove(self, value):
value = self._prepareValue(value)
- self._setDirty()
super(PersistentList, self).remove(value)
+ self._setDirty()
def reverse(self):
- self._setDirty()
super(PersistentList, self).reverse()
+ self._setDirty()
def sort(self, *args):
- self._setDirty()
super(PersistentList, self).sort(*args)
+ self._setDirty()
- def extend(self, value):
+ def extend(self, value, setDirty=True):
- values = []
for v in value:
self._storeValue(v)
- values.append(self._prepareValue(v))
- self._setDirty()
- super(PersistentList, self).extend(values)
+ self.append(self._prepareValue(v, False), False)
+ if setDirty:
+ self._setDirty()
def __getitem__(self, key):
@@ -266,14 +269,11 @@
class PersistentDict(dict, PersistentCollection):
'A persistence aware dict, tracking changes into a dirty bit.'
- def __init__(self, item, attribute, companion, initialValues=None):
+ def __init__(self, item, attribute, companion):
dict.__init__(self)
PersistentCollection.__init__(self, item, attribute, companion)
- if initialValues is not None:
- self.update(initialValues)
-
def _copy(self, item, attribute, companion, copyPolicy, copyFn):
copy = type(self)(item, attribute, companion)
@@ -284,40 +284,41 @@
if isinstance(value, repository.item.Item.Item):
value = copyFn(item, value, policy)
if value is not None:
- copy[key] = value
+ copy.__setitem__(key, value, False)
elif isinstance(value, PersistentCollection):
- copy[key] = value._copy(item, attribute, companion,
- copyPolicy, copyFn)
+ copy.__setitem__(key, value._copy(item, attribute, companion,
+ copyPolicy, copyFn), False)
else:
- copy[key] = value
+ copy.__setitem__(key, value, False)
return copy
def __delitem__(self, key):
- self._setDirty()
super(PersistentDict, self).__delitem__(key)
+ self._setDirty()
- def __setitem__(self, key, value):
+ def __setitem__(self, key, value, setDirty=True):
self._storeValue(value)
value = self._prepareValue(value)
- self._setDirty()
super(PersistentDict, self).__setitem__(key, value)
+ if setDirty:
+ self._setDirty()
+
def clear(self):
- self._setDirty()
super(PersistentDict, self).clear()
+ self._setDirty()
- def update(self, value):
+ def update(self, value, setDirty=True):
- values = {}
for k, v in value.iteritems():
self._storeValue(v)
- values[k] = self._prepareValue(v)
- self._setDirty()
- super(PersistentDict, self).update(values)
+ self.__setitem__(k, self._prepareValue(v, False), False)
+ if setDirty:
+ self._setDirty()
def setdefault(self, key, value=None):
@@ -331,11 +332,10 @@
def popitem(self):
- self._setDirty()
-
value = super(PersistentDict, self).popitem()
value = (value[0], self._restoreValue(value[1]))
-
+ self._setDirty()
+
return value
def __getitem__(self, key):
Index: chandler/repository/item/ItemRef.py
diff -u chandler/repository/item/ItemRef.py:1.86 chandler/repository/item/ItemRef.py:1.87
--- chandler/repository/item/ItemRef.py:1.86 Wed Aug 4 14:44:17 2004
+++ chandler/repository/item/ItemRef.py Thu Aug 19 11:06:25 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.86 $"
-__date__ = "$Date: 2004/08/04 21:44:17 $"
+__revision__ = "$Revision: 1.87 $"
+__date__ = "$Date: 2004/08/19 18:06:25 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -15,11 +15,12 @@
'A wrapper around a bi-directional link between two items.'
def __init__(self, item, name, other, otherName,
- otherCard=None, otherPersist=None, otherAlias=None):
+ otherCard=None, otherPersist=None, otherAlias=None,
+ setDirty=True):
super(ItemRef, self).__init__()
self.attach(item, name, other, otherName,
- otherCard, otherPersist, otherAlias)
+ otherCard, otherPersist, otherAlias, setDirty)
def _copy(self, references, item, copyItem, name, policy, copyFn):
@@ -59,7 +60,8 @@
raise DanglingRefError, '%s <-> %s' %(self._item, self._other)
def attach(self, item, name, other, otherName,
- otherCard=None, otherPersist=None, otherAlias=None):
+ otherCard=None, otherPersist=None, otherAlias=None,
+ setDirty=True):
assert item is not None, 'item is None'
assert other is not None, 'other is None'
@@ -71,7 +73,11 @@
if other.hasAttributeValue(otherName):
old = other.getAttributeValue(otherName)
if isinstance(old, RefDict):
- old.__setitem__(item._uuid, self, alias=otherAlias)
+ try:
+ sd = old._setFlag(old.SETDIRTY, setDirty)
+ old.__setitem__(item._uuid, self, alias=otherAlias)
+ finally:
+ old._setFlag(old.SETDIRTY, sd)
return
else:
if otherCard is None:
@@ -81,11 +87,16 @@
if otherCard != 'single':
old = other._refDict(otherName, name, otherPersist)
other._references[otherName] = old
- old.__setitem__(item._uuid, self, alias=otherAlias)
+ try:
+ sd = old._setFlag(old.SETDIRTY, setDirty)
+ old.__setitem__(item._uuid, self, alias=otherAlias)
+ finally:
+ old._setFlag(old.SETDIRTY, sd)
return
other.setAttributeValue(otherName, self,
- _attrDict=other._references)
+ _attrDict=other._references,
+ setDirty=setDirty)
def detach(self, item, name, other, otherName):
@@ -95,15 +106,15 @@
old._removeRef(item._uuid)
else:
other._removeRef(otherName)
+ other.setDirty(item.VDIRTY, otherName)
- other.setDirty(attribute=otherName, dirty=item.RDIRTY)
-
- def reattach(self, item, name, old, new, otherName):
+ def reattach(self, item, name, old, new, otherName, setDirty=True):
if old is not new:
self.detach(item, name, old, otherName)
self.attach(item, name, new, otherName)
- item.setDirty(attribute=name)
+ if setDirty:
+ item.setDirty(item.VDIRTY, name, item._values)
def _unload(self, item):
@@ -167,7 +178,7 @@
return 1
- def _xmlValue(self, name, item, generator, withSchema, version, flags,
+ def _xmlValue(self, name, item, generator, withSchema, version, attrs,
mode, previous=None, next=None, alias=None):
def addAttr(attrs, attr, value):
@@ -183,16 +194,13 @@
type(value))
other = self.other(item)
- attrs = { 'type': 'uuid' }
+ attrs['type'] = 'uuid'
addAttr(attrs, 'name', name)
addAttr(attrs, 'previous', previous)
addAttr(attrs, 'next', next)
addAttr(attrs, 'alias', alias)
- if flags:
- attrs['flags'] = str(flags)
-
if withSchema:
attrs['otherName'] = item._kind.getOtherName(name)
@@ -213,7 +221,8 @@
return self
def attach(self, item, name, other, otherName,
- otherCard=None, otherPersist=None, otherAlias=None):
+ otherCard=None, otherPersist=None, otherAlias=None,
+ setDirty=True):
pass
def detach(self, item, name, other, otherName):
@@ -240,12 +249,12 @@
def _refCount(self):
return 0
- def _xmlValue(self, name, item, generator, withSchema, version, flags,
+ def _xmlValue(self, name, item, generator, withSchema, version, attrs,
mode, previous=None, next=None, alias=None):
- attrs = { 'name': name, 'type': 'none' }
- if flags:
- attrs['flags'] = str(flags)
+ attrs['name'] = name
+ attrs['type'] = 'none'
+
generator.startElement('ref', attrs)
generator.endElement('ref')
@@ -364,45 +373,64 @@
self.ref = ItemRef(item, self.attrName,
ItemStub(item, self), self.otherName,
otherCard = self.otherCard,
- otherAlias = self.otherAlias)
+ otherAlias = self.otherAlias,
+ setDirty=False)
repository._addStub(self.ref)
- self.valueDict.__setitem__(self.refName, self.ref,
- self.previous, self.next, self.alias,
- False)
+
+ vd = self.valueDict
+ if vd._isRefDict():
+ try:
+ setDirty = vd._setFlag(RefDict.SETDIRTY, False)
+ vd.__setitem__(self.refName, self.ref,
+ self.previous, self.next,
+ self.alias, False)
+ finally:
+ vd._setFlag(RefDict.SETDIRTY, setDirty)
+ else:
+ vd[self.refName] = self.ref
return None
def _attach(self, item, other):
value = other._references.get(self.otherName)
+
+ def setDict(vd):
+ if vd._isRefDict():
+ try:
+ sd = vd._setFlag(RefDict.SETDIRTY, False)
+ vd.__setitem__(self.refName, value,
+ self.previous, self.next,
+ self.alias, False)
+ finally:
+ vd._setFlag(RefDict.SETDIRTY, sd)
+ else:
+ vd[self.refName] = value
if value is None or value is NoneRef:
if self.ref is not None:
self.ref.attach(item, self.attrName,
other, self.otherName,
otherCard=self.otherCard,
- otherAlias=self.otherAlias)
+ otherAlias=self.otherAlias,
+ setDirty=False)
else:
value = ItemRef(item, self.attrName,
other, self.otherName,
otherCard=self.otherCard,
- otherAlias=self.otherAlias)
- self.valueDict.__setitem__(self.refName, value,
- self.previous, self.next,
- self.alias, False)
+ otherAlias=self.otherAlias,
+ setDirty=False)
+ setDict(self.valueDict)
elif isinstance(value, ItemRef):
if isinstance(value._other, Stub):
value._other = item
- self.valueDict.__setitem__(self.refName, value,
- self.previous, self.next,
- self.alias, False)
+ setDict(self.valueDict)
elif isinstance(value._item, Stub):
value._item = item
- self.valueDict.__setitem__(self.refName, value,
- self.previous, self.next,
- self.alias, False)
+ setDict(self.valueDict)
+
else:
return value
@@ -412,15 +440,12 @@
value = value._getRef(otherRefName)
if isinstance(value._other, Stub):
value._other = item
- self.valueDict.__setitem__(self.refName, value,
- self.previous, self.next,
- self.alias, False)
+ setDict(self.valueDict)
elif isinstance(value._item, Stub):
value._item = item
- self.valueDict.__setitem__(self.refName, value,
- self.previous, self.next,
- self.alias, False)
+ setDict(self.valueDict)
+
else:
return value
@@ -429,15 +454,15 @@
self.ref.attach(item, self.attrName,
other, self.otherName,
otherCard=self.otherCard,
- otherAlias=self.otherAlias)
+ otherAlias=self.otherAlias,
+ setDirty=False)
else:
value = ItemRef(item, self.attrName,
other, self.otherName,
otherCard=self.otherCard,
- otherAlias=self.otherAlias)
- self.valueDict.__setitem__(self.refName, value,
- self.previous, self.next,
- self.alias, False)
+ otherAlias=self.otherAlias,
+ setDirty=False)
+ setDict(self.valueDict)
else:
raise ValueError, value
@@ -477,9 +502,37 @@
self._aliases = None
self._readOnly = readOnly
self._indexes = None
+ self._flags = RefDict.SETDIRTY
super(RefDict, self).__init__()
+ def _isRefDict(self):
+
+ return True
+
+ def _setFlag(self, flag, on):
+
+ old = self._flags & flag != 0
+ if on:
+ self._flags |= flag
+ else:
+ self._flags &= ~flag
+
+ return old
+
+ def _getFlag(self, flag):
+
+ return self._flags & flag != 0
+
+ def _setDirty(self, noMonitors=False):
+
+ if self._getFlag(RefDict.SETDIRTY):
+ item = self._item
+ if noMonitors:
+ item.setDirty(item.RDIRTY, self._name)
+ else:
+ item.setDirty(item.RDIRTY, self._name, item._references)
+
def _copy(self, references, item, copyItem, name, policy, copyFn):
try:
@@ -588,7 +641,12 @@
if not self._getRepository().isLoading():
self.fillIndex(index)
- self._item.setDirty(attribute=self._name, dirty=self._item.RDIRTY)
+ self._setDirty(noMonitors=True)
+
+ if indexType == 'attribute':
+ from repository.item.Monitors import Monitors
+ Monitors.attach(self._item, '_reIndex',
+ 'set', kwds['attribute'], self._name, name)
def _createIndex(self, indexType, **kwds):
@@ -608,7 +666,7 @@
def removeIndex(self, name):
del self._indexes[name]
- self._item.setDirty(attribute=self._name, dirty=self._item.RDIRTY)
+ self._setDirty(noMonitors=True)
def fillIndex(self, index):
@@ -630,8 +688,14 @@
list to this ref collection.
"""
- for value in valueList:
- self.append(value)
+ try:
+ sd = self._setFlag(RefDict.SETDIRTY, False)
+ for value in valueList:
+ self.append(value, None)
+ finally:
+ self._setFlag(RefDict.SETDIRTY, sd)
+
+ self._setDirty()
def update(self, dictionary, setAliases=False):
"""
@@ -644,12 +708,18 @@
@type setAliases: boolean
"""
- if setAliases:
- for alias, value in dictionary.iteritems():
- self.append(value, alias)
- else:
- for value in dictionary.itervalues():
- self.append(value)
+ try:
+ sd = self._setFlag(RefDict.SETDIRTY, False)
+ if setAliases:
+ for alias, value in dictionary.iteritems():
+ self.append(value, alias)
+ else:
+ for value in dictionary.itervalues():
+ self.append(value, None)
+ finally:
+ self._setFlag(RefDict.SETDIRTY, sd)
+
+ self._setDirty()
def append(self, item, alias=None):
"""
@@ -667,13 +737,19 @@
"""
Remove all references from this ref collection.
"""
-
- key = self.firstKey()
- while key is not None:
- nextKey = self.nextKey(key)
- del self[key]
- key = nextKey
+ try:
+ sd = self._setFlag(RefDict.SETDIRTY, False)
+ key = self.firstKey()
+ while key is not None:
+ nextKey = self.nextKey(key)
+ del self[key]
+ key = nextKey
+ finally:
+ self._setFlag(RefDict.SETDIRTY, sd)
+
+ self._setDirty()
+
def dir(self):
"""
Debugging: print all items referenced in this ref collection.
@@ -691,14 +767,15 @@
load=True):
loading = self._getRepository().isLoading()
- if loading and previousKey is None and nextKey is None:
- ref = self._loadRef(key)
- if ref is not None:
- previousKey, nextKey, alias = ref
+ if loading:
+ if previousKey is None and nextKey is None:
+ ref = self._loadRef(key)
+ if ref is not None:
+ previousKey, nextKey, alias = ref
old = super(RefDict, self).get(key, None, load)
if not loading:
- self._changeRef(key)
+ self._changeRef(key, None)
if old is not None:
item = self._getItem()
@@ -764,9 +841,9 @@
super(RefDict, self).place(key, afterKey)
else:
self._indexes[indexName].moveKey(key, afterKey)
- self._item.setDirty(attribute=self._name, dirty=self._item.RDIRTY)
+ self._setDirty()
- def removeItem(self, item):
+ def remove(self, item):
"""
Remove a referenced item from this reference collection.
@@ -780,18 +857,22 @@
self._removeRef(key, True)
- def _changeRef(self, key, alias=None):
+ def _changeRef(self, key, alias=None, noMonitors=False):
if self._readOnly:
raise AttributeError, 'Value for %s on %s is read-only' %(self._name, self._item.itsPath)
- self._item.setDirty(attribute=self._name, dirty=self._item.RDIRTY)
+ self._setDirty(noMonitors)
def _removeRef(self, key, _detach=False):
if self._readOnly:
raise AttributeError, 'Value for %s on %s is read-only' %(self._name, self._item.itsPath)
+ if self._indexes:
+ for index in self._indexes.itervalues():
+ index.removeKey(key)
+
value = self._getRef(key)
if _detach:
@@ -803,9 +884,6 @@
del self._aliases[link._alias]
self._count -= 1
- if self._indexes:
- for index in self._indexes.itervalues():
- index.removeKey(key)
return link
@@ -845,7 +923,7 @@
def linkChanged(self, link, key):
if key is not None:
- self._changeRef(key)
+ self._changeRef(key, noMonitors=True)
def _getRef(self, key, load=True):
@@ -986,13 +1064,13 @@
"""
self._indexes[indexName].setEntryValue(item._uuid, value)
- self._item.setDirty(attribute=self._name, dirty=self._item.RDIRTY)
+ self._setDirty()
def _refCount(self):
return len(self)
- def _xmlValue(self, name, item, generator, withSchema, version, flags,
+ def _xmlValue(self, name, item, generator, withSchema, version, attrs,
mode):
def addAttr(attrs, attr, value):
@@ -1007,7 +1085,7 @@
raise NotImplementedError, "%s, type: %s" %(value,
type(value))
- attrs = { 'name': name }
+ attrs['name'] = name
if withSchema:
attrs['cardinality'] = 'list'
@@ -1017,9 +1095,6 @@
addAttr(attrs, 'last', self._lastKey)
attrs['count'] = str(self._count)
- if flags:
- attrs['flags'] = str(flags)
-
generator.startElement('ref', attrs)
self._xmlValues(generator, version, mode)
generator.endElement('ref')
@@ -1029,7 +1104,7 @@
for key in self.iterkeys():
link = self._get(key)
link._value._xmlValue(key, self._item,
- generator, False, version, 0, mode,
+ generator, False, version, {}, mode,
previous=link._previousKey,
next=link._nextKey,
alias=link._alias)
@@ -1189,6 +1264,8 @@
return True
+ SETDIRTY = 0x0001
+
class TransientRefDict(RefDict):
"""
@@ -1198,7 +1275,7 @@
def linkChanged(self, link, key):
pass
- def _changeRef(self, key, alias=None):
+ def _changeRef(self, key, alias=None, noMonitors=False):
pass
def check(self, item, name):
More information about the Commits
mailing list