From: "Shawn O. Pearce" <spearce@spearce.org>
To: Robin Rosenberg <robin.rosenberg@dewire.com>
Cc: git@vger.kernel.org
Subject: [JGIT PATCH 11/19] Remove the map lookup for values in Config
Date: Sat, 25 Jul 2009 11:52:54 -0700 [thread overview]
Message-ID: <1248547982-4003-12-git-send-email-spearce@spearce.org> (raw)
In-Reply-To: <1248547982-4003-11-git-send-email-spearce@spearce.org>
Update operations are already O(N) time in the config file, as we
scan through every entry in the file, in order, looking to see if
it matches the key we need to mutate. As most configurations are
rather small in size the running time is trivial. Doing the same
for lookup simplifies our code considerably.
Applications really want a different type of fast lookup strategy.
Instead of by key lookups they want something like CoreConfig
or RemoteConfig to be cached and quickly obtainable on demand,
where the all relevant values have been parsed from their string
content representation into the application specific data types.
This change does not provide that functionality, but rather assumes
we will do so in the near future.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
.../src/org/spearce/jgit/lib/Config.java | 129 +++++---------------
1 files changed, 30 insertions(+), 99 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/Config.java b/org.spearce.jgit/src/org/spearce/jgit/lib/Config.java
index d63e926..0f91412 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/lib/Config.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/Config.java
@@ -43,10 +43,8 @@
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.spearce.jgit.errors.ConfigInvalidException;
@@ -66,11 +64,6 @@
final Config baseConfig;
/**
- * Map from name to values
- */
- private Map<String, Object> byName;
-
- /**
* Magic value indicating a missing entry.
* <p>
* This value is tested for reference equality in some contexts, so we
@@ -334,19 +327,9 @@ public String getString(final String section, String subsection,
*/
public String[] getStringList(final String section, String subsection,
final String name) {
- final Object o = getRawEntry(section, subsection, name);
- if (o instanceof List) {
- final List lst = (List) o;
- final String[] r = new String[lst.size()];
- for (int i = 0; i < r.length; i++)
- r[i] = ((Entry) lst.get(i)).value;
- return r;
- }
-
- if (o instanceof Entry) {
- return new String[] { ((Entry) o).value };
- }
-
+ final List<String> lst = getRawStringList(section, subsection, name);
+ if (lst != null)
+ return lst.toArray(new String[lst.size()]);
if (baseConfig != null)
return baseConfig.getStringList(section, subsection, name);
return new String[0];
@@ -373,43 +356,36 @@ public String getString(final String section, String subsection,
private String getRawString(final String section, final String subsection,
final String name) {
- final Object o = getRawEntry(section, subsection, name);
- if (o instanceof List) {
- return ((Entry) ((List) o).get(0)).value;
- } else if (o instanceof Entry) {
- return ((Entry) o).value;
- } else if (baseConfig != null)
+ final List<String> lst = getRawStringList(section, subsection, name);
+ if (lst != null)
+ return lst.get(0);
+ else if (baseConfig != null)
return baseConfig.getRawString(section, subsection, name);
else
return null;
}
- private Object getRawEntry(final String section, final String subsection,
- final String name) {
- return byName.get(concatenateKey(section, subsection, name));
+ private List<String> getRawStringList(final String section,
+ final String subsection, final String name) {
+ List<String> r = null;
+ for (final Entry e : entries) {
+ if (e.match(section, subsection, name))
+ r = add(r, e.value);
+ }
+ return r;
}
- /**
- * Create simple a key name from the key components
- *
- * @param section
- * the section name
- * @param subsection
- * the subsection name
- * @param name
- * the key name
- * @return a simple key name that have all components concatenated and the
- * case converted
- */
- private static String concatenateKey(final String section,
- final String subsection, final String name) {
- String ss;
- if (subsection != null)
- ss = "." + subsection;
- else
- ss = "";
- return StringUtils.toLowerCase(section) + ss + "."
- + StringUtils.toLowerCase(name);
+ private static List<String> add(final List<String> curr, final String value) {
+ if (curr == null)
+ return Collections.singletonList(value);
+ if (curr.size() == 1) {
+ final List<String> r = new ArrayList<String>(2);
+ r.add(curr.get(0));
+ r.add(value);
+ return r;
+ }
+ curr.add(value);
+ return curr;
}
/**
@@ -551,31 +527,6 @@ public void unset(final String section, final String subsection,
*/
public void setStringList(final String section, final String subsection,
final String name, final List<String> values) {
- // Update our parsed cache of values for future reference.
- //
- String key = concatenateKey(section, subsection, name);
- if (values.size() == 0)
- byName.remove(key);
- else if (values.size() == 1) {
- final Entry e = new Entry();
- e.section = section;
- e.subsection = subsection;
- e.name = name;
- e.value = values.get(0);
- byName.put(key, e);
- } else {
- final ArrayList<Entry> eList = new ArrayList<Entry>(values.size());
- for (final String v : values) {
- final Entry e = new Entry();
- e.section = section;
- e.subsection = subsection;
- e.name = name;
- e.value = v;
- eList.add(e);
- }
- byName.put(key, eList);
- }
-
int entryIndex = 0;
int valueIndex = 0;
int insertPosition = -1;
@@ -697,9 +648,7 @@ public String toText() {
* made to {@code this}.
*/
public void fromText(final String text) throws ConfigInvalidException {
- entries = new ArrayList<Entry>();
- byName = new HashMap<String, Object>();
-
+ final List<Entry> newEntries = new ArrayList<Entry>();
final StringReader in = new StringReader(text);
Entry last = null;
Entry e = new Entry();
@@ -711,7 +660,7 @@ public void fromText(final String text) throws ConfigInvalidException {
final char c = (char) input;
if ('\n' == c) {
// End of this entry.
- add(e);
+ newEntries.add(e);
if (e.section != null)
last = e;
e = new Entry();
@@ -757,6 +706,8 @@ public void fromText(final String text) throws ConfigInvalidException {
} else
throw new ConfigInvalidException("Invalid line in config file");
}
+
+ entries = newEntries;
}
/**
@@ -764,26 +715,6 @@ public void fromText(final String text) throws ConfigInvalidException {
*/
protected void clear() {
entries = new ArrayList<Entry>();
- byName = new HashMap<String, Object>();
- }
-
- @SuppressWarnings("unchecked")
- private void add(final Entry e) {
- entries.add(e);
- if (e.section != null && e.name != null) {
- final String key = concatenateKey(e.section, e.subsection, e.name);
- final Object o = byName.get(key);
- if (o == null) {
- byName.put(key, e);
- } else if (o instanceof Entry) {
- final ArrayList<Object> l = new ArrayList<Object>();
- l.add(o);
- l.add(e);
- byName.put(key, l);
- } else if (o instanceof List) {
- ((List<Entry>) o).add(e);
- }
- }
}
private static String readSectionName(final StringReader in)
--
1.6.4.rc2.216.g769fa
next prev parent reply other threads:[~2009-07-25 18:54 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-25 18:52 [JGIT PATCH 00/19] More Config class cleanup work Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 01/19] Cleanup nonstandard references to encoding strings to bytes Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 02/19] Delete incorrect Javadoc from Config's getRawString method Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 03/19] Make Config.escapeValue a private method Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 04/19] Allow a RemoteConfig to use the more generic Config class Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 05/19] Use type specific sets when creating a new RepositoryConfig Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 06/19] Move SystemReader out of RepositoryConfig Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 07/19] Correct user config to be of type FileBasedConfig Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 08/19] Extract the test specific SystemReader out of RepositoryTestCase Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 09/19] Refactor Config hierarchy to make IO more explicit Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 10/19] Test for the config file when creating a new repository Shawn O. Pearce
2009-07-25 18:52 ` Shawn O. Pearce [this message]
2009-07-25 18:52 ` [JGIT PATCH 12/19] Return base values first from Config.getStringList() Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 13/19] Make Config thread safe by using copy-on-write semantics Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 14/19] Support cached application models in a Config Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 15/19] Cache Config subsection names when requested by application code Shawn O. Pearce
2009-07-25 18:52 ` [JGIT PATCH 16/19] Refactor author/committer lookup to use cached data Shawn O. Pearce
2009-07-25 18:53 ` [JGIT PATCH 17/19] Move repository config creation fully into Repository class Shawn O. Pearce
2009-07-25 18:53 ` [JGIT PATCH 18/19] Use Config SectionParser cache to store daemon enable states Shawn O. Pearce
2009-07-25 18:53 ` [JGIT PATCH 19/19] Use Config cache for fetch and receive configuration parsing Shawn O. Pearce
2009-07-25 22:54 ` [JGIT PATCH 09/19] Refactor Config hierarchy to make IO more explicit Robin Rosenberg
2009-07-25 22:55 ` Shawn O. Pearce
2009-07-25 23:34 ` Robin Rosenberg
2009-07-25 23:38 ` Shawn O. Pearce
2009-07-25 20:32 ` [JGIT PATCH 02/19] Delete incorrect Javadoc from Config's getRawString method Robin Rosenberg
2009-07-25 20:33 ` Shawn O. Pearce
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1248547982-4003-12-git-send-email-spearce@spearce.org \
--to=spearce@spearce.org \
--cc=git@vger.kernel.org \
--cc=robin.rosenberg@dewire.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).