Differences between revisions 7 and 8
Revision 7 as of 2009-05-12 12:02:26
Size: 2036
Comment:
Revision 8 as of 2009-05-13 22:02:04
Size: 2896
Editor: DavidSoria
Comment: Added storage concepts
Deletions are marked like this. Additions are marked like this.
Line 24: Line 24:
== Storage ==
All keys are stored in a per-repo table. There are two possible implementations of the table. The first one would be a simple hash table that stores new elements before an existing element on a collision. This would give O(1) access to the last key, while still being able to retrieve older versions. In addition the hashtable allows to override existing entries. This would be useful for modules that do not need to store older revisions. The second implementation would split revision controlled tables with non revision controlled tables in a collision aware hashtable and a hashtable set.

There decision to use just one storage is based on a stronger regulation that avoids errors and makes the pushkey/listkeys manageable for the core, while an implementation per module would add overhead and might lead to more performance impacts.

General

The current implementation of the wire protcol in Mercurial lacks support to push and pull data that is not managed by the manifest and revlog. As a result extensions like the Bookmark Extension are not able to push their data over the wire. The following section will describe an approach to extend the wire protocol to make these usages possible.

I propose to add a pushkey and listkeys method to the wire protocol. The pushkey can be used to push a key-value-pair to a remote repository. The remote repository can determine how to update the provided information. The listkeys method can be used to pull the information from a repository and update the data locally according to the provided information.

Implementation Details

The puskey/listkeys interfaces is defined as:

  boolean pushkey  (string identifier, string key, string value, boolean force=False)
  dict    listkeys (string identifier)

The identifier determines which handler to call on the remote site. A short example:

  pushkey('bookmarks', 'my-bookmark', 'aa3dfa...')

As a result the remote site knows to forward the information to the bookmark implementation. Pushkey returns falls if an error occurs during push.

Listkeys will return a key=>value combination. Both local and remote repository have to provide the necessary "capability" to be able to push and list keys.

Push Access

The current concept does not implement any special push/pull access rules. Everybody who has allow_push rights will be able to push keys. Listing of keys is always possible.

Storage

All keys are stored in a per-repo table. There are two possible implementations of the table. The first one would be a simple hash table that stores new elements before an existing element on a collision. This would give O(1) access to the last key, while still being able to retrieve older versions. In addition the hashtable allows to override existing entries. This would be useful for modules that do not need to store older revisions. The second implementation would split revision controlled tables with non revision controlled tables in a collision aware hashtable and a hashtable set.

There decision to use just one storage is based on a stronger regulation that avoids errors and makes the pushkey/listkeys manageable for the core, while an implementation per module would add overhead and might lead to more performance impacts.

Next Steps

Add the specifics of how you control who's allowed to push keys and how they're stored.

MartinGeisler suggests that we store the data in

.hg/keys/<handler>/<keyname>

files. We would then provide a function that can serialize/deserialize basic types, dicts, tuples, and lists.

The standard pickle module is probably not good since it's not safe on malicous data.


See also ArbitraryMetadata.

PushkeyConcept (last edited 2020-01-05 06:31:05 by MattHarbison)