Hi Vishesh,
I finally looked at the remove-proxy patch again and fixed it. Now the
only problem left is the design weirdness of ResourceData instances
deleting themselves.
The main thing I did was removing all calls to determineUri from
ResourceData and moving them into Resource. I did the same with load()
and store() which is actually not necessary. Maybe it would be cleaner
to move those back...
I did not look into the merging of load and determineUri yet. I think we
should do that in a separate patch only after we cleaned this one up.
Otherwise it is impossible to debug.
Cheers,
Sebastian
On 05/26/2010 12:52 PM, Vishesh Handa wrote:
>
>
> On Wed, May 26, 2010 at 3:13 PM, Sebastian Trüg <[email protected]
> <mailto:[email protected]>> wrote:
>
> On 05/26/2010 10:08 AM, Vishesh Handa wrote:
> > > 3. When checking if the the m_kickoffUri is a nie:url for a
> resource.
> > > The nieUrl is assigned to be equal to the uri. This however
> gets fixed
> > > in the load(). And nieUrl isn't used anywhere, so it doesn't
> > matter that
> > > much.
> >
> > I suppose you mean this part:
> >
> > if( it.next() ) {
> > QUrl uri = it["r"].uri();
> > if( uri.isEmpty() ) {
> > m_uri = m_kickoffUri;
> > }
> > else {
> > m_uri = uri;
> > m_nieUrl = uri;
> > }
> >
> > The last two lines. AFAICT this is perfectly fine since in the
> latter
> > case both nie:url and resource URI are equal.
> >
> >
> > I respectfully disagree. :)
> >
> > The query used is this "select distinct ?r ?o where { { ?r nie:url
> <uri>
> > . } UNION { <uri> ?p ?o . } } LIMIT 1". The case where ?r isn't empty
> > is when the <uri> contains the nie:url and therefore ?r will
> contain the
> > resource uri.
>
> You are of course correct. It should be "m_nieUrl = m_kickoffUri"
> instead. Agreed?
>
>
> Yup. :)
>
> If you get the time could you please look at my horrible merge patch?
>
> Thanks
> - Vishesh Handa
>
> Cheers,
> Sebastian
>
>
Index: resourcemanager_p.h
===================================================================
--- resourcemanager_p.h (revision 1130392)
+++ resourcemanager_p.h (working copy)
@@ -97,7 +97,7 @@
*/
ResourceData* data( const QUrl& uri, const QUrl& type );
- bool dataCacheFull();
+ bool dataCacheFull() const;
/**
* Delete unused ResourceData objects from the cache.
@@ -115,6 +115,8 @@
*/
void determineAllUris();
+ bool shouldBeDeleted( ResourceData * rd ) const;
+
QList<ResourceData*> allResourceData();
QList<ResourceData*> allResourceDataOfType( const QUrl& type );
QList<ResourceData*> allResourceDataWithProperty( const QUrl& _uri,
const Variant& v );
Index: resourcedata.cpp
===================================================================
--- resourcedata.cpp (revision 1130802)
+++ resourcedata.cpp (working copy)
@@ -60,7 +60,6 @@
m_kickoffUri( uri ),
m_mainType( type ),
m_modificationMutex(QMutex::Recursive),
- m_proxyData(0),
m_cacheDirty(true),
m_pimoThing(0),
m_groundingOccurence(0),
@@ -102,71 +101,50 @@
QUrl Nepomuk::ResourceData::uri() const
{
- if( m_proxyData )
- return m_proxyData->uri();
return m_uri;
}
QUrl Nepomuk::ResourceData::type()
{
- if( m_proxyData )
- return m_proxyData->type();
- load();
return m_mainType;
}
QList<QUrl> Nepomuk::ResourceData::allTypes()
{
- if( m_proxyData )
- return m_proxyData->allTypes();
- load();
return m_types;
}
void Nepomuk::ResourceData::setTypes( const QList<QUrl>& types )
{
- if( m_proxyData ) {
- m_proxyData->setTypes( types );
- }
- else if ( store() ) {
- QMutexLocker lock(&m_modificationMutex);
+ Q_ASSERT(!m_uri.isEmpty());
- // reset types
- m_types.clear();
- m_mainType = Soprano::Vocabulary::RDFS::Resource();
+ QMutexLocker lock(&m_modificationMutex);
- QList<Node> nodes;
- // load types (and set maintype)
- foreach( const QUrl& url, types ) {
- loadType( url );
- nodes << Node( url );
- }
+ // reset types
+ m_types.clear();
+ m_mainType = Soprano::Vocabulary::RDFS::Resource();
- // update the data store
- MAINMODEL->updateProperty( m_uri, Soprano::Vocabulary::RDF::type(),
nodes );
+ QList<Node> nodes;
+ // load types (and set maintype)
+ foreach( const QUrl& url, types ) {
+ loadType( url );
+ nodes << Node( url );
}
+
+ // update the data store
+ MAINMODEL->updateProperty( m_uri, Soprano::Vocabulary::RDF::type(), nodes
);
}
void Nepomuk::ResourceData::resetAll( bool isDelete )
{
- // reset proxy
- bool hadProxy = false;
- if( m_proxyData ) {
- hadProxy = true;
- if( !m_proxyData->deref() &&
- rm()->dataCacheFull() )
- delete m_proxyData;
- m_proxyData = 0;
- }
-
// remove us from all caches (store() will re-insert us later if necessary)
m_rm->mutex.lock();
- if( !m_uri.isEmpty() && !hadProxy ) // if we had a proxy we were not in
m_initializedData ourselves
+ if( !m_uri.isEmpty() )
m_rm->m_initializedData.remove( m_uri );
if( !m_kickoffUri.isEmpty() )
m_rm->m_uriKickoffData.remove( m_kickoffUri );
@@ -197,23 +175,12 @@
QHash<QUrl, Nepomuk::Variant> Nepomuk::ResourceData::allProperties()
{
- if( m_proxyData )
- return m_proxyData->allProperties();
-
- load();
-
return m_cache;
}
bool Nepomuk::ResourceData::hasProperty( const QUrl& uri )
{
- if( m_proxyData )
- return m_proxyData->hasProperty( uri );
-
- if( !load() )
- return false;
-
QHash<QUrl, Variant>::const_iterator it = m_cache.constFind( uri );
if( it == m_cache.constEnd() )
return false;
@@ -224,12 +191,6 @@
bool Nepomuk::ResourceData::hasProperty( const QUrl& p, const Variant& v )
{
- if( m_proxyData )
- return m_proxyData->hasProperty( p, v );
-
- if( !load() )
- return false;
-
QHash<QUrl, Variant>::const_iterator it = m_cache.constFind( p );
if( it == m_cache.constEnd() )
return false;
@@ -246,22 +207,20 @@
bool Nepomuk::ResourceData::hasType( const QUrl& uri )
{
- if( m_proxyData )
- return m_proxyData->hasType( uri );
-
- load();
return constHasType( uri );
}
bool Nepomuk::ResourceData::constHasType( const QUrl& uri ) const
{
+ kDebug() << uri;
// we need to protect the reading, too. setTypes may be triggered from
another thread
QMutexLocker lock(&m_modificationMutex);
Types::Class requestedType( uri );
for ( QList<QUrl>::const_iterator it = m_types.constBegin();
it != m_types.constEnd(); ++it ) {
+ kDebug() << "m_types:" << *it;
Types::Class availType( *it );
if ( availType == requestedType ||
availType.isSubClassOf( requestedType ) ) {
@@ -274,39 +233,17 @@
Nepomuk::Variant Nepomuk::ResourceData::property( const QUrl& uri )
{
- if( m_proxyData )
- return m_proxyData->property( uri );
+ // we need to protect the reading, too. load my be triggered from another
thread's
+ // connection to a Soprano statement signal
+ QMutexLocker lock(&m_modificationMutex);
- if ( load() ) {
- // we need to protect the reading, too. load my be triggered from
another thread's
- // connection to a Soprano statement signal
- QMutexLocker lock(&m_modificationMutex);
-
- QHash<QUrl, Variant>::const_iterator it = m_cache.constFind( uri );
- if ( it == m_cache.constEnd() ) {
- return Variant();
- }
- else {
- return *it;
- }
+ QHash<QUrl, Variant>::const_iterator it = m_cache.constFind( uri );
+ if ( it == m_cache.constEnd() ) {
+ return Variant();
}
else {
- return Variant();
+ return *it;
}
-
-// Variant v;
-
-// if ( determineUri() ) {
-// Soprano::Model* model = m_rm->m_manager->mainModel();
-// Soprano::StatementIterator it = model->listStatements(
Soprano::Statement( m_uri, QUrl(uri), Soprano::Node() ) );
-
-// while ( it.next() ) {
-// Statement statement = *it;
-// v.append( Variant::fromNode( statement.object() ) );
-// }
-// it.close();
-// }
-// return v;
}
@@ -314,7 +251,7 @@
{
QMutexLocker lock(&m_modificationMutex);
- if ( !determineUri() ) {
+ if ( m_uri.isEmpty() ) {
QMutexLocker rmlock(&m_rm->mutex);
// create a random URI and add us to the initialized data, i.e. make
us "valid"
m_uri = m_rm->m_manager->generateUniqueUri( QString() );
@@ -422,7 +359,7 @@
if ( m_cacheDirty ) {
m_cache.clear();
- if ( determineUri() ) {
+ if ( m_uri.isValid() ) {
Soprano::QueryResultIterator it =
MAINMODEL->executeQuery(QString("select distinct ?p ?o where { "
"%1 ?p ?o . "
"}").arg(Soprano::Node::resourceToN3(m_uri)),
@@ -476,76 +413,70 @@
void Nepomuk::ResourceData::setProperty( const QUrl& uri, const
Nepomuk::Variant& value )
{
Q_ASSERT( uri.isValid() );
+ Q_ASSERT( m_uri.isValid() );
- if( m_proxyData )
- return m_proxyData->setProperty( uri, value );
-
// step 0: make sure this resource is in the store
- if ( store() ) {
- QMutexLocker lock(&m_modificationMutex);
+ QMutexLocker lock(&m_modificationMutex);
- QList<Node> valueNodes;
+ QList<Node> valueNodes;
- // make sure resource values are in the store
- if ( value.simpleType() == qMetaTypeId<Resource>() ) {
- QList<Resource> l = value.toResourceList();
- for( QList<Resource>::iterator resIt = l.begin(); resIt !=
l.end(); ++resIt ) {
- resIt->m_data->store();
- }
+ // make sure resource values are in the store
+ if ( value.simpleType() == qMetaTypeId<Resource>() ) {
+ QList<Resource> l = value.toResourceList();
+ for( QList<Resource>::iterator resIt = l.begin(); resIt != l.end();
++resIt ) {
+ resIt->m_data->store();
}
+ }
- // add the actual property statements
+ // add the actual property statements
- // one-to-one Resource
- if( value.isResource() ) {
- valueNodes.append( value.toUrl() );
- }
+ // one-to-one Resource
+ if( value.isResource() ) {
+ valueNodes.append( value.toUrl() );
+ }
- // one-to-many Resource
- else if( value.isResourceList() ) {
- const QList<QUrl>& l = value.toUrlList();
- for( QList<QUrl>::const_iterator resIt = l.constBegin(); resIt !=
l.constEnd(); ++resIt ) {
- valueNodes.append( *resIt );
- }
+ // one-to-many Resource
+ else if( value.isResourceList() ) {
+ const QList<QUrl>& l = value.toUrlList();
+ for( QList<QUrl>::const_iterator resIt = l.constBegin(); resIt !=
l.constEnd(); ++resIt ) {
+ valueNodes.append( *resIt );
}
+ }
- // one-to-many literals
- else if( value.isList() ) {
- valueNodes = Nepomuk::valuesToRDFNodes( value );
- }
+ // one-to-many literals
+ else if( value.isList() ) {
+ valueNodes = Nepomuk::valuesToRDFNodes( value );
+ }
- // one-to-one literal
- else {
- valueNodes.append( Nepomuk::valueToRDFNode( value ) );
- }
+ // one-to-one literal
+ else {
+ valueNodes.append( Nepomuk::valueToRDFNode( value ) );
+ }
- // update the cache for now
- m_cache[uri] = value;
+ // update the cache for now
+ m_cache[uri] = value;
- // update the store
- MAINMODEL->updateProperty( m_uri, uri, valueNodes );
- }
+ // update the store
+ MAINMODEL->updateProperty( m_uri, uri, valueNodes );
}
void Nepomuk::ResourceData::removeProperty( const QUrl& uri )
{
Q_ASSERT( uri.isValid() );
+ Q_ASSERT( m_uri.isValid() );
- if( m_proxyData )
- return m_proxyData->removeProperty( uri );
-
QMutexLocker lock(&m_modificationMutex);
- if ( determineUri() ) {
- m_cache.remove( uri );
- MAINMODEL->removeProperty( m_uri, uri );
- }
+ m_cache.remove( uri );
+ MAINMODEL->removeProperty( m_uri, uri );
}
void Nepomuk::ResourceData::remove( bool recursive )
{
+ Q_ASSERT( m_uri.isValid() );
+
// trueg: there is one problem we somehow need to work around:
// if we have a resource with URI X and indentifier Y and we
// create two ResourceData objects, one from X and one from Y
@@ -558,19 +489,11 @@
// That way the proxy handling will take care of the rest.
m_rm->determineAllUris();
- if( m_proxyData ) {
- m_proxyData->remove( recursive );
- }
- else {
- QMutexLocker lock(&m_modificationMutex);
+ QMutexLocker lock(&m_modificationMutex);
-
- if ( determineUri() ) {
- MAINMODEL->removeAllStatements( Statement( m_uri, Node(), Node() )
);
- if ( recursive ) {
- MAINMODEL->removeAllStatements( Statement( Node(), Node(),
m_uri ) );
- }
- }
+ MAINMODEL->removeAllStatements( Statement( m_uri, Node(), Node() ) );
+ if ( recursive ) {
+ MAINMODEL->removeAllStatements( Statement( Node(), Node(), m_uri ) );
}
resetAll();
@@ -579,179 +502,185 @@
bool Nepomuk::ResourceData::exists()
{
- if( m_proxyData )
- return m_proxyData->exists();
-
- if( determineUri() ) {
+ if( m_uri.isValid() ) {
return MAINMODEL->containsAnyStatement( Statement( m_uri, Node(),
Node() ) );
}
- else
+ else {
return false;
+ }
}
bool Nepomuk::ResourceData::isValid() const
{
- if( m_proxyData )
- return m_proxyData->isValid();
-
return( !m_mainType.isEmpty() && ( !m_uri.isEmpty() ||
!m_kickoffUri.isEmpty() || !m_kickoffId.isEmpty() ) );
}
bool Nepomuk::ResourceData::determineUri()
{
- if( m_proxyData )
- return m_proxyData->determineUri();
+ //
+ // Preconditions:
+ // 1. m_kickoffId is not a local file path or URL (use m_kickoffUri for
that)
+ //
+ // Now for the hard part
+ // We have the following possible situations:
+ // 1. m_uri is already valid
+ // -> simple, nothing to do
+ //
+ // 2. m_uri is not valid
+ // -> we need to determine the URI
+ //
+ // 2.1. m_kickoffId is valid
+ // 2.1.1. m_kickoffId is a resource URI
+ // -> use it as m_uri
+ // 2.1.2. m_kickoffId is a nao:identifier for r
+ // -> use r as m_uri
+ // 2.1.3. m_kickoffId is not found
+ // -> create new random m_uri and save m_kickoffId as nao:identifier
+ //
+ // 2.2. m_kickoffUri is valid
+ // 2.2.1. it is a file URL
+ // 2.2.1.1. it is nie:url for r
+ // -> use r as m_uri
+ // 2.2.1.2. it points to a file on a removable device for which we have a
filex:/ URL
+ // -> use the r in r nie:url filex:/...
+ // 2.2.1.3. it is a file which is not an object in some nie:url relation
+ // -> create new random m_uri and use kickoffUriOrId() as m_nieUrl
+ //
+ QMutexLocker lock(&m_determineUriMutex);
- else {
- //
- // Preconditions:
- // 1. m_kickoffId is not a local file path or URL (use m_kickoffUri
for that)
- //
- // Now for the hard part
- // We have the following possible situations:
- // 1. m_uri is already valid
- // -> simple, nothing to do
- //
- // 2. m_uri is not valid
- // -> we need to determine the URI
- //
- // 2.1. m_kickoffId is valid
- // 2.1.1. m_kickoffId is a resource URI
- // -> use it as m_uri
- // 2.1.2. m_kickoffId is a nao:identifier for r
- // -> use r as m_uri
- // 2.1.3. m_kickoffId is not found
- // -> create new random m_uri and save m_kickoffId as
nao:identifier
- //
- // 2.2. m_kickoffUri is valid
- // 2.2.1. it is a file URL
- // 2.2.1.1. it is nie:url for r
- // -> use r as m_uri
- // 2.2.1.2. it points to a file on a removable device for which we
have a filex:/ URL
- // -> use the r in r nie:url filex:/...
- // 2.2.1.3. it is a file which is not an object in some nie:url
relation
- // -> create new random m_uri and use kickoffUriOrId() as
m_nieUrl
- //
- QMutexLocker lock(&m_determineUriMutex);
+ if( m_uri.isEmpty() ) {
- if( m_uri.isEmpty() ) {
+ Soprano::Model* model = MAINMODEL;
- Soprano::Model* model = MAINMODEL;
-
- if( !m_kickoffId.isEmpty() ) {
- //
- // The kickoffUriOrId is actually a URI
- //
- KUrl uriFromKickoffId(m_kickoffId);
- if( model->containsAnyStatement( uriFromKickoffId, Node(),
Node() )) {
- m_uri = uriFromKickoffId;
- }
-
- //
- // Check if the kickoffUriOrId is a resource identifier or a
resource URI
- //
- else {
- QString query = QString::fromLatin1("select distinct ?r ?o
where { { ?r %1 %2 . } UNION { %3 ?p ?o . } . } LIMIT 1")
- .arg(
Soprano::Node::resourceToN3(Soprano::Vocabulary::NAO::identifier()) )
- .arg(
Soprano::Node::literalToN3(m_kickoffId) )
- .arg(
Soprano::Node::resourceToN3(KUrl(m_kickoffId)) );
- Soprano::QueryResultIterator it = model->executeQuery(
query, Soprano::Query::QueryLanguageSparql );
- if( it.next() ) {
- m_uri = it["r"].uri();
- if( m_uri.isEmpty() ) {
- m_uri = KUrl(m_kickoffId);
- }
- it.close();
- }
- }
+ if( !m_kickoffId.isEmpty() ) {
+ //
+ // The kickoffUriOrId is actually a URI
+ //
+ KUrl uriFromKickoffId(m_kickoffId);
+ if( model->containsAnyStatement( uriFromKickoffId, Node(), Node()
)) {
+ m_uri = uriFromKickoffId;
}
- else if( !m_kickoffUri.isEmpty() ) {
- //
- // In one query determine if the URI is already used as
resource URI or as
- // nie:url
- //
- QString query = QString::fromLatin1("select distinct ?r ?o
where { "
- "{ ?r %1 %2 .
FILTER(?r!=%2) . } "
- "UNION "
- "{ %2 ?p ?o . } "
- "} LIMIT 1")
- .arg(
Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NIE::url()) )
- .arg(
Soprano::Node::resourceToN3(m_kickoffUri) );
+ //
+ // Check if the kickoffUriOrId is a resource identifier or a
resource URI
+ //
+ else {
+ QString query = QString::fromLatin1("select distinct ?r ?o
where { { ?r %1 %2 . } UNION { %3 ?p ?o . } . } LIMIT 1")
+ .arg(
Soprano::Node::resourceToN3(Soprano::Vocabulary::NAO::identifier()) )
+ .arg( Soprano::Node::literalToN3(m_kickoffId) )
+ .arg(
Soprano::Node::resourceToN3(KUrl(m_kickoffId)) );
Soprano::QueryResultIterator it = model->executeQuery( query,
Soprano::Query::QueryLanguageSparql );
if( it.next() ) {
- QUrl uri = it["r"].uri();
- if( uri.isEmpty() ) {
- m_uri = m_kickoffUri;
+ m_uri = it["r"].uri();
+ if( m_uri.isEmpty() ) {
+ m_uri = KUrl(m_kickoffId);
}
- else {
- m_uri = uri;
- m_nieUrl = m_kickoffUri;
- }
it.close();
}
- else if( m_kickoffUri.scheme() == QLatin1String("file") ) {
- //
- // This is the hard part: The file may still be saved
using a filex:/ URL
- // We have to determine if that is the case. For that we
need to look if the URL
- // starts with any of the mounted filesystems' mount paths
and then reconstruct
- // the filex:/ URL. Since that is quite some work which
involved Solid and, thus,
- // DBus calls we simply call the removable storage service
directly.
- //
- // If there is no resource yet we create a new uri in
store()
- //
+ }
+ }
- //
- // We create a new dbus connection to protect us from
multi-thread related crashes.
- //
- KUrl resourceUri = QDBusReply<QString>(
QDBusInterface(QLatin1String("org.kde.nepomuk.services.nepomukremovablestorageservice"),
-
QLatin1String("/nepomukremovablestorageservice"),
-
QLatin1String("org.kde.nepomuk.RemovableStorage"),
-
DBusConnectionPool::threadConnection())
- .call(
QLatin1String("resourceUriFromLocalFileUrl"),
-
m_kickoffUri.url() ) ).value();
- if( !resourceUri.isEmpty() ) {
- m_uri = resourceUri;
- }
-
- m_nieUrl = m_kickoffUri;
- }
- else if( m_kickoffUri.scheme() == QLatin1String("nepomuk") ) {
- // for nepomuk URIs we simply use the kickoff URI as
resource URI
+ else if( !m_kickoffUri.isEmpty() ) {
+ //
+ // In one query determine if the URI is already used as resource
URI or as
+ // nie:url
+ //
+ QString query = QString::fromLatin1("select distinct ?r ?o where {
"
+ "{ ?r %1 %2 . FILTER(?r!=%2) .
} "
+ "UNION "
+ "{ %2 ?p ?o . } "
+ "} LIMIT 1")
+ .arg(
Soprano::Node::resourceToN3(Nepomuk::Vocabulary::NIE::url()) )
+ .arg( Soprano::Node::resourceToN3(m_kickoffUri) );
+ Soprano::QueryResultIterator it = model->executeQuery( query,
Soprano::Query::QueryLanguageSparql );
+ if( it.next() ) {
+ QUrl uri = it["r"].uri();
+ if( uri.isEmpty() ) {
m_uri = m_kickoffUri;
}
else {
- // for everything else we use m_kickoffUri as nie:url with
a new random m_uri
+ m_uri = uri;
m_nieUrl = m_kickoffUri;
}
+ it.close();
}
+ else if( m_kickoffUri.scheme() == QLatin1String("file") ) {
+ //
+ // This is the hard part: The file may still be saved using a
filex:/ URL
+ // We have to determine if that is the case. For that we need
to look if the URL
+ // starts with any of the mounted filesystems' mount paths and
then reconstruct
+ // the filex:/ URL. Since that is quite some work which
involved Solid and, thus,
+ // DBus calls we simply call the removable storage service
directly.
+ //
+ // If there is no resource yet we create a new uri in store()
+ //
+ //
+ // We create a new dbus connection to protect us from
multi-thread related crashes.
+ //
+ KUrl resourceUri = QDBusReply<QString>(
QDBusInterface(QLatin1String("org.kde.nepomuk.services.nepomukremovablestorageservice"),
+
QLatin1String("/nepomukremovablestorageservice"),
+
QLatin1String("org.kde.nepomuk.RemovableStorage"),
+
DBusConnectionPool::threadConnection())
+ .call(
QLatin1String("resourceUriFromLocalFileUrl"),
+
m_kickoffUri.url() ) ).value();
+ if( !resourceUri.isEmpty() ) {
+ m_uri = resourceUri;
+ }
+
+ m_nieUrl = m_kickoffUri;
+ }
+ else if( m_kickoffUri.scheme() == QLatin1String("nepomuk") ) {
+ // for nepomuk URIs we simply use the kickoff URI as resource
URI
+ m_uri = m_kickoffUri;
+ }
else {
- // no kickoff values. We will only create a new random URI in
store()
- return false;
+ // for everything else we use m_kickoffUri as nie:url with a
new random m_uri
+ m_nieUrl = m_kickoffUri;
}
+ }
- //
- // Move us to the final data hash now that the URI is known
- //
- if( !m_uri.isEmpty() ) {
- QMutexLocker rmlock(&m_rm->mutex);
+ else {
+ // no kickoff values. We will only create a new random URI in
store()
+ return false;
+ }
- ResourceDataHash::iterator it =
m_rm->m_initializedData.find(m_uri);
- if( it == m_rm->m_initializedData.end() ) {
- m_rm->m_initializedData.insert( m_uri, this );
- }
- else {
- m_proxyData = it.value();
- m_proxyData->ref();
- }
+ //
+ // Move us to the final data hash now that the URI is known
+ //
+ if( !m_uri.isEmpty() ) {
+ QMutexLocker rmlock(&m_rm->mutex);
+
+ ResourceDataHash::iterator it =
m_rm->m_initializedData.find(m_uri);
+ if( it == m_rm->m_initializedData.end() ) {
+ m_rm->m_initializedData.insert( m_uri, this );
}
+ else {
+ // As the ResourceData already exists in m_initializedData, we
simply
+ // make all the the Resources which contain "this"
ResourceData, point
+ // to the initialized ResourceData instead.
+ replaceWith( it.value() );
+ }
}
+ }
- return !m_uri.isEmpty();
+ return !m_uri.isEmpty();
+}
+
+
+void Nepomuk::ResourceData::replaceWith(Nepomuk::ResourceData* rd)
+{
+ foreach( Resource * res, m_resources) {
+ ResourceData * oldData = res->m_data;
+ if ( oldData && !oldData->deref( res ) && rm()->shouldBeDeleted(
oldData ) )
+ delete oldData;
+
+ res->m_data = rd;
+ res->m_data->ref( res );
}
+ delete this;
}
@@ -770,7 +699,6 @@
Nepomuk::Thing Nepomuk::ResourceData::pimoThing()
{
- load();
if( !m_pimoThing ) {
if( hasType( Vocabulary::PIMO::Thing() ) ) {
kDebug() << "we are already a thing. Creating link to ourself" <<
m_uri << this;
@@ -796,17 +724,13 @@
bool Nepomuk::ResourceData::operator==( const ResourceData& other ) const
{
- const ResourceData* that = this;
- if( m_proxyData )
- that = m_proxyData;
-
- if( that == &other )
+ if( this == &other )
return true;
- return( that->m_uri == other.m_uri &&
- that->m_mainType == other.m_mainType &&
- that->m_kickoffUri == other.m_kickoffUri &&
- that->m_kickoffId == other.m_kickoffId );
+ return( m_uri == other.m_uri &&
+ m_mainType == other.m_mainType &&
+ m_kickoffUri == other.m_kickoffUri &&
+ m_kickoffId == other.m_kickoffId );
}
@@ -818,8 +742,7 @@
m_uri.url(),
m_mainType.toString())
.arg(m_ref);
- if(m_proxyData)
- dbg << QLatin1String(", proxy: " ) << *m_proxyData;
+
return dbg << QLatin1String("]");
}
Index: resourcemanager.cpp
===================================================================
--- resourcemanager.cpp (revision 1130838)
+++ resourcemanager.cpp (working copy)
@@ -197,7 +197,7 @@
}
-bool Nepomuk::ResourceManagerPrivate::dataCacheFull()
+bool Nepomuk::ResourceManagerPrivate::dataCacheFull() const
{
return dataCnt >= 1000;
}
@@ -230,6 +230,17 @@
}
+bool Nepomuk::ResourceManagerPrivate::shouldBeDeleted( ResourceData * rd )
const
+{
+ //
+ // We delete data objects in one of two cases:
+ // 1. They are not valid and as such not in one of the
ResourceManagerPrivate kickoff lists
+ // 2. The cache is already full and we need to clean up
+ //
+ return( !rd->cnt() && ( !rd->isValid() || dataCacheFull() ));
+}
+
+
void Nepomuk::ResourceManagerPrivate::_k_storageServiceInitialized( bool
success )
{
if( success ) {
Index: resourcedata.h
===================================================================
--- resourcedata.h (revision 1130392)
+++ resourcedata.h (working copy)
@@ -37,6 +37,7 @@
namespace Nepomuk {
+ class Resource;
class ResourceManagerPrivate;
class ResourceData
@@ -45,11 +46,16 @@
explicit ResourceData( const QUrl& uri, const QString& kickoffId_,
const QUrl& type_, ResourceManagerPrivate* rm );
~ResourceData();
- inline bool ref() {
+ inline bool ref(Nepomuk::Resource* res) {
+ QMutexLocker lock(&m_resourcesMutex);
+ m_resources.push_back( res );
return m_ref.ref();
}
- inline bool deref() {
+
+ inline bool deref(Nepomuk::Resource* res) {
+ QMutexLocker lock(&m_resourcesMutex);
+ m_resources.removeAll( res );
return m_ref.deref();
}
@@ -139,6 +145,10 @@
* Searches for the resource in the Nepomuk store using m_kickoffId
and m_kickoffUri.
*
* \returns true if the resource was found and m_uri is set, false
otherwise.
+ *
+ * Caution: This method might delete this instance of ResourceData and
replace it
+ * with another one in all referencing Resource instances. It should
never be called
+ * from within ResourceData methods!
*/
bool determineUri();
@@ -155,7 +165,7 @@
ResourceManagerPrivate* rm() const { return m_rm; }
- ResourceData* proxy() const { return m_proxyData; }
+ bool shouldBeDeleted() const;
private:
void loadType( const QUrl& type );
@@ -187,13 +197,15 @@
QMutex m_determineUriMutex;
mutable QMutex m_modificationMutex;
+ /// Contains a list of resources which contain this ResourceData
+ QList<Resource *> m_resources;
+ QMutex m_resourcesMutex;
+
/**
- * Used to virtually merge two data objects representing the same
- * resource. This happens if the resource was once created using its
- * actual URI and once via its ID. To prevent early loading we allow
- * this scenario.
+ * Makes the m_data pointer of all the Resources in m_resources point
to
+ * rd, instead of 'this'. Handles refernce counting as well.
*/
- ResourceData* m_proxyData;
+ void replaceWith( ResourceData* rd );
QHash<QUrl, Variant> m_cache;
bool m_cacheDirty;
Index: resource.cpp
===================================================================
--- resource.cpp (revision 1130818)
+++ resource.cpp (working copy)
@@ -47,14 +47,16 @@
Nepomuk::Resource::Resource()
{
m_data = ResourceManager::instance()->d->data( QUrl(), QUrl() );
- m_data->ref();
+ if ( m_data )
+ m_data->ref( this );
}
Nepomuk::Resource::Resource( ResourceManager* manager )
{
m_data = manager->d->data( QUrl(), QUrl() );
- m_data->ref();
+ if ( m_data )
+ m_data->ref( this );
}
@@ -62,7 +64,7 @@
{
m_data = res.m_data;
if ( m_data )
- m_data->ref();
+ m_data->ref( this );
}
@@ -70,7 +72,7 @@
{
m_data = ResourceManager::instance()->d->data( uri, type );
if ( m_data )
- m_data->ref();
+ m_data->ref( this );
}
@@ -78,7 +80,7 @@
{
m_data = manager->d->data( uri, type );
if ( m_data )
- m_data->ref();
+ m_data->ref( this );
}
@@ -86,7 +88,7 @@
{
m_data = ResourceManager::instance()->d->data( uri, type );
if ( m_data )
- m_data->ref();
+ m_data->ref( this );
}
@@ -94,7 +96,7 @@
{
m_data = ResourceManager::instance()->d->data( uri, type );
if ( m_data )
- m_data->ref();
+ m_data->ref( this );
}
@@ -102,7 +104,7 @@
{
m_data = manager->d->data( uri, type );
if ( m_data )
- m_data->ref();
+ m_data->ref( this );
}
@@ -110,26 +112,16 @@
{
m_data = data;
if ( m_data )
- data->ref();
+ m_data->ref( this );
}
Nepomuk::Resource::~Resource()
{
if ( m_data ) {
- if ( !m_data->deref() ) {
- //
- // We delete data objects in one of three cases:
- // 1. They are not valid and as such not in one of the
ResourceManagerPrivate kickoff lists
- // 2. They have a proxy which is the actual thing to reuse later on
- // 3. The cache is already full and we need to clean up
- //
- if ( !m_data->isValid() ||
- m_data->proxy() ||
- m_data->rm()->dataCacheFull() ) {
- delete m_data;
- }
- }
+ m_data->deref( this );
+ if ( m_data->rm()->shouldBeDeleted( m_data ) )
+ delete m_data;
}
}
@@ -137,12 +129,12 @@
Nepomuk::Resource& Nepomuk::Resource::operator=( const Resource& res )
{
if( m_data != res.m_data ) {
- if ( m_data && !m_data->deref() && !m_data->isValid() ) {
+ if ( m_data && !m_data->deref( this ) &&
m_data->rm()->shouldBeDeleted( m_data ) ) {
delete m_data;
}
m_data = res.m_data;
if ( m_data )
- m_data->ref();
+ m_data->ref( this );
}
return *this;
@@ -187,36 +179,33 @@
QUrl Nepomuk::Resource::resourceType() const
{
- if ( m_data ) {
- return m_data->type();
- }
- else {
- return QUrl();
- }
+ m_data->determineUri();
+ m_data->load();
+ return m_data->type();
}
QList<QUrl> Nepomuk::Resource::types() const
{
- if ( m_data ) {
- return m_data->allTypes();
- }
- else {
- return QList<QUrl>();
- }
+ m_data->determineUri();
+ m_data->load();
+ return m_data->allTypes();
}
void Nepomuk::Resource::setTypes( const QList<QUrl>& types )
{
- if ( m_data )
+ m_data->determineUri();
+ if ( m_data->store() ) {
m_data->setTypes( types );
+ }
}
void Nepomuk::Resource::addType( const QUrl& type )
{
- if ( m_data ) {
+ m_data->determineUri();
+ if ( m_data->store() ) {
QList<QUrl> tl = types();
if( !tl.contains( type ) )
setTypes( tl << type );
@@ -226,7 +215,13 @@
bool Nepomuk::Resource::hasType( const QUrl& typeUri ) const
{
- return m_data ? m_data->hasType( typeUri ) : false;
+ m_data->determineUri();
+ if ( m_data->load() ) {
+ return m_data->hasType( typeUri );
+ }
+ else {
+ return false;
+ }
}
@@ -238,7 +233,8 @@
QHash<QUrl, Nepomuk::Variant> Nepomuk::Resource::properties() const
{
- if ( m_data ) {
+ m_data->determineUri();
+ if ( m_data->load() ) {
return m_data->allProperties();
}
else {
@@ -262,13 +258,25 @@
bool Nepomuk::Resource::hasProperty( const QUrl& uri ) const
{
- return m_data ? m_data->hasProperty( uri ) : false;
+ m_data->determineUri();
+ if ( m_data->load() ) {
+ return m_data->hasProperty( uri );
+ }
+ else {
+ return false;
+ }
}
bool Nepomuk::Resource::hasProperty( const Types::Property& p, const Variant&
v ) const
{
- return m_data ? m_data->hasProperty( p.uri(), v ) : false;
+ m_data->determineUri();
+ if ( m_data->load() ) {
+ return m_data->hasProperty( p.uri(), v );
+ }
+ else {
+ return false;
+ }
}
@@ -286,7 +294,8 @@
Nepomuk::Variant Nepomuk::Resource::property( const QUrl& uri ) const
{
- if ( m_data ) {
+ m_data->determineUri();
+ if ( m_data->load() ) {
return m_data->property( uri );
}
else {
@@ -311,7 +320,8 @@
void Nepomuk::Resource::setProperty( const QUrl& uri, const Nepomuk::Variant&
value )
{
- if ( m_data ) {
+ m_data->determineUri();
+ if ( m_data->store() ) {
m_data->setProperty( uri, value );
}
}
@@ -325,7 +335,7 @@
void Nepomuk::Resource::removeProperty( const QUrl& uri )
{
- if ( m_data ) {
+ if ( m_data && m_data->determineUri() ) {
m_data->removeProperty( uri );
}
}
@@ -333,19 +343,17 @@
void Nepomuk::Resource::removeProperty( const QUrl& uri, const Variant& value )
{
- if ( m_data ) {
- QList<Variant> vl = property( uri ).toVariantList();
- foreach( const Variant& v, value.toVariantList() ) {
- vl.removeAll( v );
- }
- setProperty( uri, Variant( vl ) );
+ QList<Variant> vl = property( uri ).toVariantList();
+ foreach( const Variant& v, value.toVariantList() ) {
+ vl.removeAll( v );
}
+ setProperty( uri, Variant( vl ) );
}
void Nepomuk::Resource::remove()
{
- if ( m_data ) {
+ if ( m_data && m_data->determineUri() ) {
m_data->remove();
}
}
@@ -353,7 +361,12 @@
bool Nepomuk::Resource::exists() const
{
- return m_data ? m_data->exists() : false;
+ if ( m_data && m_data->determineUri() ) {
+ return m_data->exists();
+ }
+ else {
+ return false;
+ }
}
@@ -478,7 +491,8 @@
Nepomuk::Thing Nepomuk::Resource::pimoThing()
{
- if( m_data ) {
+ m_data->determineUri();
+ if( m_data->load() ) {
return m_data->pimoThing();
}
else {
_______________________________________________
Nepomuk mailing list
[email protected]
https://mail.kde.org/mailman/listinfo/nepomuk