Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated append method to keep an "_end" hint. Purpose is to address … #612

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 64 additions & 20 deletions rdflib/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Collection(object):
def __init__(self, graph, uri, seq=[]):
self.graph = graph
self.uri = uri or BNode()
self._end = self.uri
for item in seq:
self.append(item)

Expand Down Expand Up @@ -169,10 +170,25 @@ def __delitem__(self, key):
>>> len(g)
4

>>> from rdflib.graph import Namespace
>>> from rdflib.collection import Collection
>>> g = Graph()
>>> EX = Namespace("http://example.org/ex#")
>>> c = Collection(g, BNode(), [EX[str(i)] for i in range(1,10)])
>>> len(c)
9
>>> del c[0]
>>> len(c)
8
>>> del c[8]
>>> len(c)
7

"""
self[key] # to raise any potential key exceptions
graph = self.graph
current = self._get_container(key)
self._end = self.uri
assert current
if len(self) == 1 and key > 0:
pass
Expand All @@ -194,7 +210,7 @@ def __iter__(self):

def append(self, item):
"""
>>> from rdflib.graph import Graph
>>> from rdflib.graph import Graph, Namespace
>>> listName = BNode()
>>> g = Graph()
>>> c = Collection(g,listName,[Literal(1),Literal(2)])
Expand All @@ -203,30 +219,58 @@ def append(self, item):
>>> len([i for i in links if (i,RDF.rest, RDF.nil) in g])
1

The following test can take a long time if append is not implemented correctly
>>> from rdflib.graph import Namespace
>>> from rdflib.collection import Collection
>>> g = Graph()
>>> EX = Namespace("http://example.org/ex#")
>>> c = Collection(g, BNode(), [EX[str(i)] for i in range(1,10000)])
>>> len(c)
9999
>>> c.append(EX['new'])
>>> str(c[-1])
'http://example.org/ex#1'
>>> del c[9999]
>>> len(c)
9999
>>> str(c[9998])
'http://example.org/ex#9999'
>>> c.clear()
>>> c.append(EX['1'])
>>> len(c)
1
"""
container = self.uri
graph = self.graph
# iterate to the end of the linked list
rest = graph.value(container, RDF.rest)
while rest:
if rest == RDF.nil:
# the end, append to the end of the linked list
node = BNode()
graph.set((container, RDF.rest, node))
container = node
break
else:
# move down one link
if container != self.uri:
rest = graph.value(rest, RDF.rest)
if not rest == RDF.nil:
container = rest
graph.add((container, RDF.first, item))
graph.add((container, RDF.rest, RDF.nil))
if graph.value(self._end, RDF.rest) == RDF.nil:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer (self._end, RDF.rest, RDF.nil) in graph, which may also be slightly faster?

container = BNode()
graph.set((self._end, RDF.rest, container))
graph.add((container, RDF.first, item))
graph.add((container, RDF.rest, RDF.nil))
else:
container = self.uri
# iterate to the end of the linked list
rest = graph.value(container, RDF.rest)
while rest:
if rest == RDF.nil:
# the end, append to the end of the linked list
node = BNode()
graph.set((container, RDF.rest, node))
container = node
break
else:
# move down one link
if container != self.uri:
rest = graph.value(rest, RDF.rest)
if not rest == RDF.nil:
container = rest
graph.add((container, RDF.first, item))
graph.add((container, RDF.rest, RDF.nil))
self._end = container

def clear(self):
container = self.uri
graph = self.graph
self._end = self.uri
while container:
rest = graph.value(container, RDF.rest)
graph.remove((container, RDF.first, None))
Expand Down Expand Up @@ -260,7 +304,7 @@ def test():

try:
del c[500]
except IndexError, i:
except IndexError as i:
pass

c.append(Literal("5"))
Expand Down