You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2012/10/17 17:59:10 UTC
svn commit: r1399318 - in /subversion/trunk/notes/directory-index:
dirindex.py schema.sql
Author: brane
Date: Wed Oct 17 15:59:09 2012
New Revision: 1399318
URL: http://svn.apache.org/viewvc?rev=1399318&view=rev
Log:
Work in progress: new filesystem index prototype.
* notes/directory-index/schema.sql
(branch): Remove table and all associated queries.
(txn): Add trigger for populating initial treeid.
(noderev): noderev.id replaces previous usage of branch.id in the noderev
table; noderev.nodeid and noderev.branchid default to it for new
branches/nodes.
-- Add appropriate trigger to populate these columns, and branch index.
(TXN_UPDATE_INITIAL_TREEID): Removed, replaced by trigger.
(NODEREV_COUNT_SUCCESSORS): Removed.
(NODEVIEW_LIST_DIRECTORY, NODEVIEW_LIST_TRANSIENT_DIRECTORY):
Fix bug in treeid filter subquery.
* notes/directory-index/dirindex.py (SQLclass.__init__): Remove redundant import.
(Txn._put): Initial treeid is now populated by trigger.
(Branch): Remove, including all references.
(NodeRev.__str__): Include noderev.id in output.
(NodeRev._put): Reflect trigger actions in wrapped object.
(NodeRev._count_successors): Removed.
(NodeRev._branch, NodeRev._revise): Fix implementation.
(NodeRev.__setitem__): Better handling of virtual fields name and dename.
(__greek_tree, greektree): New; populate index with the greek tree.
(simpletest): Reimplement using greektree. Fix recursive dir listing.
Modified:
subversion/trunk/notes/directory-index/dirindex.py
subversion/trunk/notes/directory-index/schema.sql
Modified: subversion/trunk/notes/directory-index/dirindex.py
URL: http://svn.apache.org/viewvc/subversion/trunk/notes/directory-index/dirindex.py?rev=1399318&r1=1399317&r2=1399318&view=diff
==============================================================================
--- subversion/trunk/notes/directory-index/dirindex.py (original)
+++ subversion/trunk/notes/directory-index/dirindex.py Wed Oct 17 15:59:09 2012
@@ -42,7 +42,6 @@ class SQLclass(object):
def __init__(self):
import cStringIO
import pkgutil
- import re
comment_rx = re.compile(r"\s*--.*$")
header_rx = re.compile(r"^---(?P<kind>STATEMENT|SCRIPT)"
@@ -215,7 +214,6 @@ class Txn(SQLobject):
self.created = self._now()
super(Txn, self)._put(cursor)
if self.treeid is None:
- SQL.TXN_UPDATE_INITIAL_TREEID(cursor, id = self.id)
self.treeid = self.id
@classmethod
@@ -253,49 +251,6 @@ class Txn(SQLobject):
SQL.TXN_CLEANUP(cursor, id = self.id)
-class Branch(SQLobject):
- """O/R mapping for the "branch" table."""
-
- _columns = ("id", "treeid", "nodeid", "origin", "state")
- _put_statement = SQL.BRANCH_INSERT
- _get_statement = SQL.BRANCH_GET
-
- # state
- TRANSIENT = "T"
- PERMANENT = "P"
-
- def __init__(self, **kwargs):
- super(Branch, self).__init__(**kwargs)
- if self.state is None:
- self.state = self.TRANSIENT
-
- def _put(self, cursor):
- super(Branch, self)._put(cursor)
- if self.nodeid is None:
- SQL.BRANCH_UPDATE_INITIAL_NODEID(cursor, id = self.id)
- self.nodeid = self.id
-
- @classmethod
- def _update_treeid(cls, cursor, new_txn, old_txn):
- SQL.BRANCH_UPDATE_TREEID(cursor,
- new_treeid = new_txn.treeid,
- old_treeid = old_txn.treeid)
-
- @classmethod
- def _history(cls, cursor, nodeid):
- SQL.BRANCH_HISTORY(cursor, nodeid = nodeid)
- for row in cursor:
- yield cls._from_row(row)
-
- @classmethod
- def _commit(cls, cursor, txn):
- SQL.BRANCH_COMMIT(cursor, treeid = txn.treeid)
-
- @classmethod
- def _cleanup(cls, cursor, txn):
- SQL.BRANCH_CLEANUP(cursor, treeid = txn.treeid)
-
-
class NodeRev(SQLobject):
"""O/R mapping for the noderev/string/nodeview table."""
@@ -330,8 +285,8 @@ class NodeRev(SQLobject):
self.state = self.TRANSIENT
def __str__(self):
- return "%d %c %s%s" % (self.treeid, self.opcode, self.name,
- self._isdir and '/' or '')
+ return "%d(%d) %c %s%s" % (self.id, self.treeid, self.opcode,
+ self.name, self._isdir and '/' or '')
# Opcode names
__opnames = {ADD: "add",
@@ -384,6 +339,10 @@ class NodeRev(SQLobject):
assert self.dename is not None
self.denameid = self.__stringid(cursor, self.dename)
super(NodeRev, self)._put(cursor)
+ if self.nodeid is None:
+ self.nodeid = self.id
+ if self.branch is None:
+ self.branch = self.id
@classmethod
def _update_treeid(cls, cursor, new_txn, old_txn):
@@ -472,10 +431,6 @@ class NodeRev(SQLobject):
track.close(cls.__find(cursor, parent.branch, parts[-1], txn))
return track
- def _count_successors(self, cursor):
- SQL.NODEREV_COUNT_SUCCESSORS(cursor, origin = self.id)
- return int(cursor.fetchone()[0])
-
def _listdir(self, cursor, txn):
assert self._isdir
if txn.state != txn.PERMANENT:
@@ -501,17 +456,13 @@ class NodeRev(SQLobject):
def _branch(self, cursor, parent, txn, replaced=False):
assert txn._uncommitted
- branch = Branch(treeid = txn.treeid,
- nodeid = self.nodeid,
- origin = self.branch)
- branch._put(cursor)
if self._isdir:
opcode = replaced and self.LAZY_BREPLACE or self.LAZY
else:
opcode = replaced and self.BREPLACE or self.BRANCH
node = self._revise(opcode, txn)
node.parent = parent.id
- node.branch = branch.id
+ node.branch = None
node._put(cursor)
return node
@@ -519,7 +470,9 @@ class NodeRev(SQLobject):
assert txn._uncommitted
noderev = NodeRev._clone(self)
noderev.treeid = txn.treeid
+ noderev.origin = self.id
noderev.opcode = opcode
+ return noderev
__readonly = frozenset(("name",))
def __setitem__(self, key, value):
@@ -528,7 +481,10 @@ class NodeRev(SQLobject):
if key == "dename":
name = self.__normtext(value)
value = self.__text(value)
- super(NodeRev, self).__setitem__("name", name)
+ if name != self.name:
+ super(NodeRev, self).__setitem__("name", name)
+ super(NodeRev, self).__setitem__("nameid", None)
+ super(NodeRev, self).__setitem__("denameid", None)
super(NodeRev, self).__setitem__(key, value)
def __getitem__(self, key):
@@ -680,12 +636,10 @@ class Index(object):
def commit_txn(self, txn, revision):
txn._commit(self.cursor, revision)
NodeRev._commit(self.cursor, txn)
- Branch._commit(self.cursor, txn)
def abort_txn(self, txn):
txn._abort(self.cursor)
NodeRev._cleanup(self.cursor, txn)
- Branch._cleanup(self.cursor, txn)
txn._cleanup(self.cursor)
def listdir(self, txn, noderev):
@@ -743,11 +697,9 @@ class Index(object):
newnode = origin._branch(self.cursor, parent.id, txn,
replaced = (oldnode is not None))
else:
- branch = Branch(treeid = txn.treeid)
- branch._put(self.cursor)
newnode = NodeRev(treeid = txn.treeid,
- nodeid = branch.nodeid,
- branch = branch.id,
+ nodeid = None,
+ branch = None,
parent = parent.id,
kind = kind,
opcode = opcode)
@@ -777,6 +729,45 @@ class Tree(object):
index.rollback()
+__greek_tree = {
+ 'iota': 'file',
+ 'A': {
+ 'mu': 'file',
+ 'B': {
+ 'lambda': 'file',
+ 'E': {
+ 'alpha': 'file',
+ 'beta': 'file'},
+ 'F': 'dir'},
+ 'C': 'dir',
+ 'D': {
+ 'G': {
+ 'pi': 'file',
+ 'rho': 'file',
+ 'tau': 'file'},
+ 'H': {
+ 'chi': 'file',
+ 'psi': 'file',
+ 'omega': 'file'}
+ }
+ }
+ }
+def greektree(ix, tx):
+ def populate(track, items):
+ print 'Populating', track
+ for name, kind in items.iteritems():
+ if kind == 'file':
+ node = ix.add(tx, track, name, NodeRev.FILE)
+ else:
+ node = ix.add(tx, track, name, NodeRev.DIR)
+ print 'Added', node, 'node:', node.noderev
+ if isinstance(kind, dict):
+ populate(node, kind)
+
+ root = ix.lookup(tx)
+ populate(root, __greek_tree)
+
+
def simpletest(database):
ix = Index(database)
ix.initialize()
@@ -789,37 +780,34 @@ def simpletest(database):
print "root track:", root
print "root noderev", root.noderev
- print "Add A/foo"
+ print 'Create greek tree'
tx = ix.new_txn(0)
print "transaction:", tx
- parent = ix.add(tx, root, "A", NodeRev.DIR)
- print "A track:", parent
- print "A noderev", parent.noderev
-
- node = ix.add(tx, parent, "foo", NodeRev.FILE)
- print "foo track:", node
- print "foo noderev", node.noderev
+ greektree(ix, tx)
ix.commit_txn(tx, 1)
ix.commit()
+
+ def listdir(noderev, prefix):
+ for n in ix.listdir(tx, noderev):
+ print prefix, str(n)
+ if n._isdir:
+ listdir(n, prefix + " ")
+
print "List contents"
tx = ix.get_txn()
print "transaction:", tx
root = ix.lookup(tx)
print str(root.noderev)
- for n1 in ix.listdir(tx, root.noderev):
- print " ", str(n1)
- if n1._isdir:
- for n2 in ix.listdir(tx, n1):
- print " ", str(n2)
-
- print "Lookup A"
- track = ix.lookup(tx, None, "A")
- print str(track.noderev)
-
- print "Lookup A/foo"
- track = ix.lookup(tx, None, "A/foo")
- print str(track.noderev)
+ listdir(root.noderev, " ")
+
+ print "Lookup iota"
+ track = ix.lookup(tx, None, "iota")
+ print str(track), str(track.noderev)
+
+ print "Lookup A/D/H/psi"
+ track = ix.lookup(tx, None, "A/D/H/psi")
+ print str(track), str(track.noderev)
finally:
ix.close()
Modified: subversion/trunk/notes/directory-index/schema.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/notes/directory-index/schema.sql?rev=1399318&r1=1399317&r2=1399318&view=diff
==============================================================================
--- subversion/trunk/notes/directory-index/schema.sql (original)
+++ subversion/trunk/notes/directory-index/schema.sql Wed Oct 17 15:59:09 2012
@@ -22,7 +22,6 @@
DROP VIEW IF EXISTS nodeview;
DROP TABLE IF EXISTS noderev;
DROP TABLE IF EXISTS string;
-DROP TABLE IF EXISTS branch;
DROP TABLE IF EXISTS txn;
@@ -61,36 +60,10 @@ CREATE TABLE txn (
CREATE INDEX txn_revision_idx ON txn(revision);
-
--- Branches -- unique forks in the nodes' history
-CREATE TABLE branch (
- -- branch identifier
- id integer NOT NULL PRIMARY KEY,
-
- -- the transaction in which the branch was created
- treeid integer NOT NULL REFERENCES txn(id),
-
- -- the node to which this branch belongs; refers to the initial
- -- branch of the node
- nodeid integer NULL REFERENCES branch(id),
-
- -- the source branch from which this branch was forked
- origin integer NULL REFERENCES branch(id),
-
- -- mark branches in uncommitted transactions so that they can be
- -- ignored by branch traversals
- -- T = transient (uncommitted), P = permanent (committed)
- state character(1) NOT NULL DEFAULT 'T',
-
- -- sanity check: enumerated value validation
- CONSTRAINT enumeration_validation CHECK (state IN ('T', 'P')),
-
- -- sanity check: ye can't be yer own daddy
- CONSTRAINT genetic_diversity CHECK (id <> origin)
-);
-
-CREATE INDEX branch_txn_idx ON branch(treeid);
-CREATE INDEX branch_node_idx ON branch(nodeid);
+CREATE TRIGGER txn_ensure_treeid AFTER INSERT ON txn
+BEGIN
+ UPDATE txn SET treeid = NEW.id WHERE treeid IS NULL AND id = NEW.id;
+END;
-- File names -- lookup table of strings
@@ -108,18 +81,19 @@ CREATE TABLE noderev (
-- the transaction in which the node was changed
treeid integer NOT NULL REFERENCES txn(id),
- -- the node identifier; a new node will get the ID of its initial
- -- branch
- nodeid integer NOT NULL REFERENCES branch(id),
+ -- the node identifier
+ -- a new node will get the ID of its initial noderev.id
+ nodeid integer NULL REFERENCES noderev(id),
-- this node revision's immediate predecessor
origin integer NULL REFERENCES noderev(id),
-- the parent (directory) of this node revision -- tree graph
- parent integer NULL REFERENCES branch(id),
+ parent integer NULL REFERENCES noderev(id),
-- the branch that this node revision belongs to -- history graph
- branch integer NOT NULL REFERENCES branch(id),
+ -- a new branch will get the ID of its initial noderev.id
+ branch integer NULL REFERENCES noderev(id),
-- the indexable, NFC-normalized name of this noderev within its parent
nameid integer NOT NULL REFERENCES string(id),
@@ -171,8 +145,15 @@ CREATE TABLE noderev (
CREATE UNIQUE INDEX noderev_tree_idx ON noderev(parent,nameid,treeid,opcode);
CREATE INDEX noderev_txn_idx ON noderev(treeid);
CREATE INDEX nodefev_node_idx ON noderev(nodeid);
+CREATE INDEX noderev_branch_idx ON noderev(branch);
CREATE INDEX noderev_successor_idx ON noderev(origin);
+CREATE TRIGGER noderev_ensure_node_and_branch AFTER INSERT ON noderev
+BEGIN
+ UPDATE noderev SET nodeid = NEW.id WHERE nodeid IS NULL AND id = NEW.id;
+ UPDATE noderev SET branch = NEW.id WHERE branch IS NULL AND id = NEW.id;
+END;
+
CREATE VIEW nodeview AS
SELECT
@@ -188,7 +169,6 @@ CREATE VIEW nodeview AS
INSERT INTO txn (id, treeid, revision, created, state)
VALUES (0, 0, 0, 'EPOCH', 'P');
-INSERT INTO branch (id, treeid, nodeid, state) VALUES (0, 0, 0, 'P');
INSERT INTO string (id, val) VALUES (0, '');
INSERT INTO noderev (id, treeid, nodeid, branch,
nameid, denameid, kind, opcode, state)
@@ -199,9 +179,6 @@ INSERT INTO noderev (id, treeid, nodeid,
INSERT INTO txn (treeid, revision, created, author)
VALUES (:treeid, :revision, :created, :author);
----STATEMENT TXN_UPDATE_INITIAL_TREEID
-UPDATE txn SET treeid = :id WHERE id = :id;
-
---STATEMENT TXN_GET
SELECT * FROM txn WHERE id = :id;
@@ -230,28 +207,6 @@ UPDATE txn SET state = 'D' WHERE id = :i
---STATEMENT TXN_CLEANUP
DELETE FROM txn WHERE id = :id;
----STATEMENT BRANCH_INSERT
-INSERT INTO branch (nodeid, treeid, origin)
- VALUES (:nodeid, :treeid, :origin);
-
----STATEMENT BRANCH_UPDATE_INITIAL_NODEID
-UPDATE branch SET nodeid = :id WHERE id = :id;
-
----STATEMENT BRANCH_UPDATE_TREEID
-UPDATE branch SET treeid = :new_treeid WHERE treeid = :old_treeid;
-
----STATEMENT BRANCH_GET
-SELECT * FROM branch WHERE id = :id;
-
----STATEMENT BRANCH_HISTORY
-SELECT * from branch WHERE nodeid = :nodeid ORDER BY id ASC;
-
----STATEMENT BRANCH_COMMIT
-UPDATE branch SET state = 'P' WHERE treeid = :treeid;
-
----STATEMENT BRANCH_CLEANUP
-DELETE FROM branch WHERE treeid = :treeid;
-
---STATEMENT STRING_INSERT
INSERT INTO string (val) VALUES (:val);
@@ -273,9 +228,6 @@ UPDATE noderev SET opcode = :opcode WHER
---STATEMENT NODEVIEW_GET
SELECT * FROM nodeview WHERE id = :id;
----STATEMENT NODEREV_COUNT_SUCCESSORS
-SELECT COUNT(id) FROM noderev WHERE origin = :origin;
-
---STATEMENT NODEREV_COMMIT
UPDATE noderev SET state = 'P' WHERE treeid = :treeid;
@@ -309,7 +261,8 @@ ORDER BY treeid DESC LIMIT 1;
---STATEMENT NODEVIEW_LIST_DIRECTORY
SELECT * FROM nodeview
JOIN (SELECT nameid, MAX(treeid) AS treeid FROM noderev
- WHERE treeid <= :treeid AND state = 'P') AS filter
+ WHERE treeid <= :treeid AND state = 'P'
+ GROUP BY nameid) AS filter
ON nodeview.nameid = filter.nameid AND nodeview.treeid = filter.treeid
WHERE parent = :parent AND opcode <> 'D'
ORDER BY nodeview.name ASC;
@@ -317,7 +270,8 @@ ORDER BY nodeview.name ASC;
---STATEMENT NODEVIEW_LIST_TRANSIENT_DIRECTORY
SELECT * FROM nodeview
JOIN (SELECT nameid, MAX(treeid) AS treeid FROM noderev
- WHERE treeid < :treeid AND state = 'P' OR treeid = :treeid) AS filter
+ WHERE treeid < :treeid AND state = 'P' OR treeid = :treeid
+ GROUP BY nameid) AS filter
ON nodeview.nameid = filter.name AND nodeview.treeid = filter.treeid
WHERE parent = :parent AND opcode <> 'D'
ORDER BY nodeview.name ASC;