[Commits] (vajda) - implemented name store
commits at osafoundation.org
commits at osafoundation.org
Fri Apr 9 12:23:10 PDT 2004
Commit by: vajda
Modified files:
osaf/chandler/Chandler/repository/item/Item.py 1.117 1.118
osaf/chandler/Chandler/repository/item/ItemHandler.py 1.35 1.36
osaf/chandler/Chandler/repository/item/ItemRef.py 1.65 1.66
osaf/chandler/Chandler/repository/persistence/DBContainer.py 1.8 1.9
osaf/chandler/Chandler/repository/persistence/XMLRepository.py 1.69 1.70
osaf/chandler/Chandler/repository/persistence/XMLRepositoryView.py 1.32 1.33
osaf/chandler/Chandler/repository/util/UUID.py 1.11 1.12
osaf/chandler/Chandler/repository/util/ext/pyuuid.c 1.3 1.4
Log message:
- implemented name store
- ref aliases no longer saved in XML but in name store
- find by path no longer involves a query and XML, uses name store instead
ViewCVS links:
http://cvs.osafoundation.org/index.cgi/osaf/chandler/Chandler/repository/item/Item.py.diff?r1=text&tr1=1.117&r2=text&tr2=1.118
http://cvs.osafoundation.org/index.cgi/osaf/chandler/Chandler/repository/item/ItemHandler.py.diff?r1=text&tr1=1.35&r2=text&tr2=1.36
http://cvs.osafoundation.org/index.cgi/osaf/chandler/Chandler/repository/item/ItemRef.py.diff?r1=text&tr1=1.65&r2=text&tr2=1.66
http://cvs.osafoundation.org/index.cgi/osaf/chandler/Chandler/repository/persistence/DBContainer.py.diff?r1=text&tr1=1.8&r2=text&tr2=1.9
http://cvs.osafoundation.org/index.cgi/osaf/chandler/Chandler/repository/persistence/XMLRepository.py.diff?r1=text&tr1=1.69&r2=text&tr2=1.70
http://cvs.osafoundation.org/index.cgi/osaf/chandler/Chandler/repository/persistence/XMLRepositoryView.py.diff?r1=text&tr1=1.32&r2=text&tr2=1.33
http://cvs.osafoundation.org/index.cgi/osaf/chandler/Chandler/repository/util/UUID.py.diff?r1=text&tr1=1.11&r2=text&tr2=1.12
http://cvs.osafoundation.org/index.cgi/osaf/chandler/Chandler/repository/util/ext/pyuuid.c.diff?r1=text&tr1=1.3&r2=text&tr2=1.4
Index: osaf/chandler/Chandler/repository/persistence/DBContainer.py
diff -u osaf/chandler/Chandler/repository/persistence/DBContainer.py:1.8 osaf/chandler/Chandler/repository/persistence/DBContainer.py:1.9
--- osaf/chandler/Chandler/repository/persistence/DBContainer.py:1.8 Tue Mar 23 21:08:47 2004
+++ osaf/chandler/Chandler/repository/persistence/DBContainer.py Fri Apr 9 12:22:37 2004
@@ -1,9 +1,11 @@
-__revision__ = "$Revision: 1.8 $"
-__date__ = "$Date: 2004/03/24 05:08:47 $"
+__revision__ = "$Revision: 1.9 $"
+__date__ = "$Date: 2004/04/09 19:22:37 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
+import UUIDext
+
from struct import pack, unpack
from repository.util.UUID import UUID
@@ -68,9 +70,27 @@
def _logDL(self, n):
self.store.repository.logger.info('detected deadlock: %d', n)
-
+
class RefContainer(DBContainer):
+
+ def _readValue(self, value, offset):
+
+ code = value[offset]
+ offset += 1
+
+ if code == '\0':
+ return (17, UUID(value[offset:offset+16]))
+
+ if code == '\1':
+ len, = unpack('>H', value[offset:offset+2])
+ offset += 2
+ return (len + 3, value[offset:offset+len])
+
+ if code == '\2':
+ return (1, None)
+
+ raise ValueError, code
def loadRef(self, version, key, cursorKey):
@@ -137,24 +157,6 @@
if txnStarted:
self.store._abortTransaction()
- def _readValue(self, value, offset):
-
- code = value[offset]
- offset += 1
-
- if code == '\0':
- return (17, UUID(value[offset:offset+16]))
-
- if code == '\1':
- len, = unpack('>H', value[offset:offset+2])
- offset += 2
- return (len + 3, value[offset:offset+len])
-
- if code == '\2':
- return (1, None)
-
- raise ValueError, code
-
# has to run within the commit() transaction
def deleteItem(self, item):
@@ -331,3 +333,71 @@
finally:
cursor.close()
+
+
+class NamesContainer(DBContainer):
+
+ def writeName(self, key, name, version, uuid):
+
+ if isinstance(name, unicode):
+ name = name.encode('utf-8')
+
+ if uuid is None:
+ uuid = key
+
+ self.put(pack('>16sll', key._uuid, UUIDext.hash(name), ~version),
+ uuid._uuid)
+
+ def readName(self, key, name, version):
+
+ if isinstance(name, unicode):
+ name = name.encode('utf-8')
+
+ cursorKey = pack('>16sl', key._uuid, UUIDext.hash(name))
+
+ while True:
+ txnStarted = False
+ cursor = None
+
+ try:
+ txnStarted = self.store._startTransaction()
+ cursor = self.cursor()
+
+ try:
+ value = cursor.set_range(cursorKey, flags=DB_DIRTY_READ)
+ except DBNotFoundError:
+ return None
+ except DBLockDeadlockError:
+ if txnStarted:
+ self._logDL(8)
+ continue
+ else:
+ raise
+
+ try:
+ while value is not None and value[0].startswith(cursorKey):
+ nameVer = ~unpack('>l', value[0][-4:])[0]
+
+ if nameVer <= version:
+ if value[1] == value[0][0:16]: # removed name
+ return None
+
+ return UUID(value[1])
+
+ else:
+ value = cursor.next()
+
+ except DBLockDeadlockError:
+ if txnStarted:
+ self._logDL(9)
+ continue
+ else:
+ raise
+
+ return None
+
+ finally:
+ if cursor:
+ cursor.close()
+ if txnStarted:
+ self.store._abortTransaction()
Index: osaf/chandler/Chandler/repository/item/Item.py
diff -u osaf/chandler/Chandler/repository/item/Item.py:1.117 osaf/chandler/Chandler/repository/item/Item.py:1.118
--- osaf/chandler/Chandler/repository/item/Item.py:1.117 Wed Mar 31 13:24:19 2004
+++ osaf/chandler/Chandler/repository/item/Item.py Fri Apr 9 12:22:36 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.117 $"
-__date__ = "$Date: 2004/03/31 21:24:19 $"
+__revision__ = "$Revision: 1.118 $"
+__date__ = "$Date: 2004/04/09 19:22:36 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -1205,9 +1205,14 @@
self.removeAttributeValue(name, _attrDict=self._references)
- self.itsParent._removeItem(self)
+ parent = self.itsParent
+
+ parent._removeItem(self)
self._setRoot(None)
+ if not '_origName' in self.__dict__:
+ self.__dict__['_origName'] = (parent.itsUUID, self._name)
+
self._status |= Item.DELETED | Item.STALE
self._status &= ~Item.DELETING
@@ -1354,11 +1359,16 @@
@type name: a string
"""
- parent = self.itsParent
- link = parent._children._get(self._name)
- parent._removeItem(self)
- self._name = name or self._uuid.str64()
- parent._addItem(self, link._previousKey, link._nextKey)
+ if name != self._name:
+ origName = self._name
+ parent = self.itsParent
+ link = parent._children._get(self._name)
+ parent._removeItem(self)
+ self._name = name or self._uuid.str64()
+ parent._addItem(self, link._previousKey, link._nextKey)
+ if not '_origName' in self.__dict__:
+ self.__dict__['_origName'] = (parent.itsUUID, origName)
+
def move(self, newParent, previous=None, next=None):
"""
@@ -1388,6 +1398,8 @@
if parent is not newParent:
parent._removeItem(self)
self._setParent(newParent, previous, next)
+ if not '_origName' in self.__dict__:
+ self.__dict__['_origName'] = (parent.itsUUID, self._name)
def _isRepository(self):
return False
Index: osaf/chandler/Chandler/repository/util/UUID.py
diff -u osaf/chandler/Chandler/repository/util/UUID.py:1.11 osaf/chandler/Chandler/repository/util/UUID.py:1.12
--- osaf/chandler/Chandler/repository/util/UUID.py:1.11 Mon Mar 8 14:56:57 2004
+++ osaf/chandler/Chandler/repository/util/UUID.py Fri Apr 9 12:22:38 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.11 $"
-__date__ = "$Date: 2004/03/08 22:56:57 $"
+__revision__ = "$Revision: 1.12 $"
+__date__ = "$Date: 2004/04/09 19:22:38 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -60,7 +60,7 @@
self._uuid = state
self._hash = UUIDext.hash(state)
-
+
def __eq__(self, other):
return isinstance(other, UUID) and self._uuid == other._uuid
Index: osaf/chandler/Chandler/repository/persistence/XMLRepository.py
diff -u osaf/chandler/Chandler/repository/persistence/XMLRepository.py:1.69 osaf/chandler/Chandler/repository/persistence/XMLRepository.py:1.70
--- osaf/chandler/Chandler/repository/persistence/XMLRepository.py:1.69 Thu Apr 1 11:51:40 2004
+++ osaf/chandler/Chandler/repository/persistence/XMLRepository.py Fri Apr 9 12:22:37 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.69 $"
-__date__ = "$Date: 2004/04/01 19:51:40 $"
+__revision__ = "$Revision: 1.70 $"
+__date__ = "$Date: 2004/04/09 19:22:37 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -17,6 +17,7 @@
from repository.persistence.XMLRepositoryView import XMLRepositoryClientView
from repository.persistence.DBContainer import DBContainer, RefContainer
from repository.persistence.DBContainer import VerContainer, HistContainer
+from repository.persistence.DBContainer import NamesContainer
from repository.persistence.FileContainer import FileContainer, BlockContainer
from repository.persistence.FileContainer import IndexContainer
@@ -166,11 +167,9 @@
self._xml.open(txn, DB_DIRTY_READ | DB_THREAD)
def attachView(self, view):
-
pass
def detachView(self, view):
-
pass
def loadItem(self, version, uuid):
@@ -193,45 +192,11 @@
def loadChild(self, version, uuid, name):
- store = self.store
- ctx = store.ctx
- ctx.setVariableValue("name", XmlValue(name.encode('utf-8')))
- ctx.setVariableValue("uuid", XmlValue(uuid.str64()))
- ctx.setVariableValue("version", XmlValue(float(version)))
-
- doc = None
- ver = 0
- txnStarted = False
-
- try:
- txnStarted = store._startTransaction()
- if self.version in ('1.2.0', '1.2.1'):
- for value in self._xml.queryWithXPath(store.txn,
- self.store.containerExpr,
- DB_DIRTY_READ):
- result = value.asDocument()
- dv = self.getDocVersion(result)
- if dv > ver:
- ver = dv
- doc = result
-
- if doc is not None:
- value = XmlValue()
- if (doc.getMetaData('', 'deleted', value) and
- value.asString() == 'True'):
- doc = None
- else:
- uuid = self.getDocUUID(doc)
- if store._versions.getDocVersion(uuid, version) != ver:
- doc = None
-
- return doc
-
- raise ValueError, "dbxml %s not supported" %(self.version)
+ uuid = self.store._names.readName(uuid, name, version)
+ if uuid is None:
+ return None
- finally:
- if txnStarted:
- store._abortTransaction()
+ return self.loadItem(version, uuid)
def loadRoots(self, version):
@@ -368,6 +333,7 @@
self._data = XMLContainer(self, "__data__", txn, create)
self._refs = RefContainer(self, "__refs__", txn, create)
+ self._names = NamesContainer(self, "__names__", txn, create)
self._versions = VerContainer(self, "__versions__", txn, create)
self._history = HistContainer(self, "__history__", txn, create)
self._text = FileContainer(self, "__text__", txn, create)
@@ -382,6 +348,7 @@
self._data.close()
self._refs.close()
+ self._names.close()
self._versions.close()
self._history.close()
self._text.close()
@@ -393,6 +360,7 @@
self._data.attachView(view)
self._refs.attachView(view)
+ self._names.attachView(view)
self._versions.attachView(view)
self._history.attachView(view)
self._text.attachView(view)
@@ -404,6 +372,7 @@
self._data.detachView(view)
self._refs.detachView(view)
+ self._names.detachView(view)
self._versions.detachView(view)
self._history.detachView(view)
self._text.detachView(view)
@@ -524,21 +493,7 @@
return updateCtx
- def _getContainerExpr(self):
-
- try:
- return self._threaded.containerExpr
- except AttributeError:
- xml = self._data._xml
- xpath = "/item[container=$uuid and name=$name and number(@version)<=$version]"
- containerExpr = xml.parseXPathExpression(None, xpath, self.ctx)
- self._threaded.containerExpr = containerExpr
-
- return containerExpr
-
-
env = property(_getEnv)
ctx = property(_getCtx)
updateCtx = property(_getUpdateCtx)
- containerExpr = property(_getContainerExpr)
txn = property(_getTxn, _setTxn)
Index: osaf/chandler/Chandler/repository/item/ItemHandler.py
diff -u osaf/chandler/Chandler/repository/item/ItemHandler.py:1.35 osaf/chandler/Chandler/repository/item/ItemHandler.py:1.36
--- osaf/chandler/Chandler/repository/item/ItemHandler.py:1.35 Thu Apr 1 11:51:39 2004
+++ osaf/chandler/Chandler/repository/item/ItemHandler.py Fri Apr 9 12:22:36 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.35 $"
-__date__ = "$Date: 2004/04/01 19:51:39 $"
+__revision__ = "$Revision: 1.36 $"
+__date__ = "$Date: 2004/04/09 19:22:36 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -296,14 +296,6 @@
else:
value = self.collections.pop()
self.references[attrs['name']] = value
-
- def aliasEnd(self, itemHandler, attrs):
-
- refDict = self.collections[-1]
- if refDict._aliases is None:
- refDict._aliases = {}
-
- refDict._aliases[attrs['name']] = UUID(self.data)
def dbEnd(self, itemHandler, attrs):
Index: osaf/chandler/Chandler/repository/item/ItemRef.py
diff -u osaf/chandler/Chandler/repository/item/ItemRef.py:1.65 osaf/chandler/Chandler/repository/item/ItemRef.py:1.66
--- osaf/chandler/Chandler/repository/item/ItemRef.py:1.65 Wed Mar 31 13:24:19 2004
+++ osaf/chandler/Chandler/repository/item/ItemRef.py Fri Apr 9 12:22:36 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.65 $"
-__date__ = "$Date: 2004/03/31 21:24:19 $"
+__revision__ = "$Revision: 1.66 $"
+__date__ = "$Date: 2004/04/09 19:22:36 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -557,8 +557,9 @@
if alias:
link._alias = alias
if self._aliases is None:
- self._aliases = {}
- self._aliases[alias] = key
+ self._aliases = { alias: key }
+ else:
+ self._aliases[alias] = key
if not loading:
self._count += 1
@@ -640,7 +641,7 @@
if key is not None:
self._changeRef(key)
- def _changeRef(self, key):
+ def _changeRef(self, key, alias=None):
self._item.setDirty(attribute=self._name, dirty=self._item.RDIRTY)
@@ -656,15 +657,28 @@
return default
- def getByAlias(self, alias):
+ def getByAlias(self, alias, load=True):
'Get the item referenced through the alias.'
-
- return self[self._aliases[alias]]
+
+ key = None
+
+ if self._aliases is not None:
+ key = self._aliases.get(alias)
+
+ if key is None and load:
+ key = self.resolveAlias(alias)
+
+ if key is None:
+ raise KeyError, alias
+
+ return self[key]
def resolveAlias(self, alias):
- """Resolve the alias to its corresponding reference key.
+ """
+ Resolve the alias to its corresponding reference key.
- Returns None if alias does not exist."""
+ Returns None if alias does not exist.
+ """
if self._aliases:
return self._aliases.get(alias)
@@ -806,7 +820,7 @@
def linkChanged(self, link, key):
pass
- def _changeRef(self, key):
+ def _changeRef(self, key, alias=None):
pass
def check(self, item, name):
Index: osaf/chandler/Chandler/repository/util/ext/pyuuid.c
diff -u osaf/chandler/Chandler/repository/util/ext/pyuuid.c:1.3 osaf/chandler/Chandler/repository/util/ext/pyuuid.c:1.4
--- osaf/chandler/Chandler/repository/util/ext/pyuuid.c:1.3 Mon Aug 11 17:28:18 2003
+++ osaf/chandler/Chandler/repository/util/ext/pyuuid.c Fri Apr 9 12:22:39 2004
@@ -64,7 +64,7 @@
unsigned int len = 0;
PyArg_ParseTuple(args, "s#", &uuid, &len);
- if (len != 16)
+ if (len < 0)
return Py_BuildValue("");
return Py_BuildValue("l", hash_uuid(uuid, len));
Index: osaf/chandler/Chandler/repository/persistence/XMLRepositoryView.py
diff -u osaf/chandler/Chandler/repository/persistence/XMLRepositoryView.py:1.32 osaf/chandler/Chandler/repository/persistence/XMLRepositoryView.py:1.33
--- osaf/chandler/Chandler/repository/persistence/XMLRepositoryView.py:1.32 Wed Mar 31 13:24:26 2004
+++ osaf/chandler/Chandler/repository/persistence/XMLRepositoryView.py Fri Apr 9 12:22:37 2004
@@ -1,6 +1,6 @@
-__revision__ = "$Revision: 1.32 $"
-__date__ = "$Date: 2004/03/31 21:24:26 $"
+__revision__ = "$Revision: 1.33 $"
+__date__ = "$Date: 2004/04/09 19:22:37 $"
__copyright__ = "Copyright (c) 2002 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -159,6 +159,7 @@
repository = self.repository
store = repository.store
data = store._data
+ names = store._names
versions = store._versions
history = store._history
env = repository._env
@@ -199,7 +200,8 @@
for item in self._log:
size += self._saveItem(item, newVersion,
- data, versions, history, ood)
+ data, names, versions, history,
+ ood)
if newVersion > self.version:
histNotifications = RepositoryNotifications(repository)
@@ -280,7 +282,7 @@
datetime.now() - before)
self.prune(10000)
- def _saveItem(self, item, newVersion, data, versions, history, ood):
+ def _saveItem(self, item, newVersion, data, names, versions, history, ood):
uuid = item._uuid
isNew = item.isNew()
@@ -328,20 +330,29 @@
raise
if isDeleted:
- parent=item.itsParent.itsUUID
+ parent, name = item.__dict__['_origName']
versions.setDocVersion(uuid, newVersion, 0)
history.writeVersion(uuid, newVersion, 0, item._status, parent)
self._notifications.changed(uuid, 'deleted', parent=parent)
+ names.writeName(parent, name, newVersion, None)
else:
versions.setDocVersion(uuid, newVersion, docId)
history.writeVersion(uuid, newVersion, docId, item._status)
if isNew:
+ names.writeName(item.itsParent.itsUUID, item._name,
+ newVersion, uuid)
self._notifications.changed(uuid, 'added')
else:
+ if '_origName' in item.__dict__:
+ parent, name = item.__dict__['_origName']
+ names.writeName(parent, name, newVersion, None)
+ names.writeName(item.itsParent.itsUUID, item._name,
+ newVersion, uuid)
+ del item.__dict__['_origName']
self._notifications.changed(uuid, 'changed')
-
+
return size
def _mergeItems(self, items, oldVersion, newVersion, history):
@@ -417,17 +428,18 @@
return self.view.repository.store._refs.loadRef(version, key,
cursorKey)
- def _changeRef(self, key):
+ def _changeRef(self, key, alias=None):
if not self.view.isLoading():
- self._log.append((0, key))
+ self._log.append((0, key, alias))
- super(XMLRefDict, self)._changeRef(key)
+ super(XMLRefDict, self)._changeRef(key, alias)
def _removeRef(self, key, _detach=False):
if not self.view.isLoading():
- self._log.append((1, key))
+ link = self._get(key, load=False)
+ self._log.append((1, key, link._alias))
self._deletedRefs[key] = key
else:
raise ValueError, 'detach during load'
@@ -456,7 +468,13 @@
self._value.write('\0')
self._value.write(value._uuid)
- elif isinstance(value, str) or isinstance(value, unicode):
+ elif isinstance(value, str):
+ self._value.write('\1')
+ self._value.write(pack('>H', len(value)))
+ self._value.write(value)
+
+ elif isinstance(value, unicode):
+ value = value.encode('utf-8')
self._value.write('\1')
self._value.write(pack('>H', len(value)))
self._value.write(value)
@@ -472,6 +490,20 @@
self.view.repository.store._refs.delete(self._packKey(key))
+ def resolveAlias(self, alias):
+
+ key = None
+
+ if self._aliases:
+ key = self._aliases.get(alias)
+
+ if key is None:
+ view = self.view
+ key = view.repository.store._names.readName(self._uuid, alias,
+ view.version)
+
+ return key
+
def _setItem(self, item):
if self._item is not None and self._item is not item:
@@ -504,13 +536,14 @@
def _xmlValues(self, generator, version, mode):
if mode == 'save':
- for entry in self._log:
+ names = self.view.repository.store._names
+ for op, key, oldAlias in self._log:
try:
- value = self._get(entry[1])
+ value = self._get(key, load=False)
except KeyError:
value = None
- if entry[0] == 0:
+ if op == 0: # change
if value is not None:
ref = value._value
previous = value._previousKey
@@ -518,14 +551,22 @@
alias = value._alias
uuid = ref.other(self._item).itsUUID
- self._writeRef(entry[1], version,
+ self._writeRef(key, version,
uuid, previous, next, alias)
+ if oldAlias is not None:
+ names.writeName(self._uuid, oldAlias,
+ version, None)
+ if alias is not None:
+ names.writeName(self._uuid, alias,
+ version, uuid)
- elif entry[0] == 1:
- self._writeRef(entry[1], version, None, None, None, None)
+ elif op == 1: # remove
+ self._writeRef(key, version, None, None, None, None)
+ if oldAlias is not None:
+ names.writeName(key, version, oldAlias, None)
- else:
- raise ValueError, entry[0]
+ else: # error
+ raise ValueError, op
if self._log:
self.view._notifications.changed(self._item._uuid, self._name)
@@ -534,11 +575,6 @@
self._deletedRefs.clear()
if len(self) > 0:
- if self._aliases:
- for key, value in self._aliases.iteritems():
- generator.startElement('alias', { 'name': key })
- generator.characters(value.str64())
- generator.endElement('alias')
generator.startElement('db', {})
generator.characters(self._uuid.str64())
generator.endElement('db')
More information about the Commits
mailing list