changeset 576:0dfa9ed1039a

Reuse strings
author Dmitry Neverov <dmitry.neverov@jetbrains.com>
date Wed, 27 Mar 2013 13:46:14 +0400
parents 19503fefd1c9
children a9fea2d1d6c8
files mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java
diffstat 2 files changed, 50 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java	Wed Mar 27 13:45:19 2013 +0400
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialCollectChangesPolicy.java	Wed Mar 27 13:46:14 2013 +0400
@@ -226,10 +226,12 @@
     List<ChangeSetRevision> parents = cset.getParents();
     if (parents.isEmpty())
       throw new IllegalStateException("Commit " + cset.getId() + " has no parents");
-    List<VcsChange> files = toVcsChanges(cset.getModifiedFiles(), parents.get(0).getId(), cset.getId(), checkoutRules);
-    final ModificationData result = new ModificationData(cset.getTimestamp(), files, cset.getDescription(), cset.getUser(), root, cset.getId(), cset.getId());
+    String version = ctx.getStringFromPool(cset.getId());
+    List<VcsChange> files = toVcsChanges(ctx, cset.getModifiedFiles(), ctx.getStringFromPool(parents.get(0).getId()), version, checkoutRules);
+    final ModificationData result = new ModificationData(cset.getTimestamp(), files, cset.getDescription(),
+            ctx.getStringFromPool(cset.getUser()), root, version, version);
     for (ChangeSetRevision parent : parents) {
-      result.addParentRevision(parent.getId());
+      result.addParentRevision(ctx.getStringFromPool(parent.getId()));
     }
     setCanBeIgnored(result, cset);
     result.setAttributes(getAttributes(ctx, root, cset));
@@ -248,13 +250,26 @@
   }
 
 
-  private List<VcsChange> toVcsChanges(final List<FileStatus> modifiedFiles, String prevVer, String curVer, CheckoutRules rules) {
-    List<VcsChange> files = new ArrayList<VcsChange>();
+  private List<VcsChange> toVcsChanges(@NotNull OperationContext ctx,
+                                       @NotNull List<FileStatus> modifiedFiles,
+                                       @NotNull String prevVer,
+                                       @NotNull String curVer,
+                                       @NotNull CheckoutRules rules) {
+    List<VcsChange> files = new ArrayList<VcsChange>(0);
     for (FileStatus mf: modifiedFiles) {
-      final String path = rules.map(mf.getPath());
-      if (shouldInclude(path))
-        files.add(toVcsChange(mf, prevVer, curVer, path));
+      String path = rules.map(mf.getPath());
+      if (!shouldInclude(path))
+        continue;
+      String normalizedPath = PathUtil.normalizeSeparator(mf.getPath());
+      VcsChangeInfo.Type changeType = getChangeType(mf.getStatus());
+      if (changeType == null) {
+        Loggers.VCS.warn("Unable to convert status: " + mf.getStatus() + " to VCS change type");
+        changeType = VcsChangeInfo.Type.NOT_CHANGED;
+      }
+      files.add(new VcsChange(changeType, mf.getStatus().getName(), ctx.getStringFromPool(normalizedPath), ctx.getStringFromPool(path), prevVer, curVer));
     }
+    if (files.isEmpty())
+      return emptyList();
     return files;
   }
 
@@ -264,17 +279,6 @@
   }
 
 
-  private VcsChange toVcsChange(FileStatus mf, String prevVer, String curVer, String mappedPath) {
-    String normalizedPath = PathUtil.normalizeSeparator(mf.getPath());
-    VcsChangeInfo.Type changeType = getChangeType(mf.getStatus());
-    if (changeType == null) {
-      Loggers.VCS.warn("Unable to convert status: " + mf.getStatus() + " to VCS change type");
-      changeType = VcsChangeInfo.Type.NOT_CHANGED;
-    }
-    return new VcsChange(changeType, mf.getStatus().getName(), normalizedPath, mappedPath, prevVer, curVer);
-  }
-
-
   private VcsChangeInfo.Type getChangeType(final Status status) {
     switch (status) {
       case ADDED:return VcsChangeInfo.Type.ADDED;
@@ -355,7 +359,7 @@
         ServerHgRepo repo = myVcs.createRepo(ctx, root);
         SubrepoConfigChangesAttributes builder = new SubrepoConfigChangesAttributes();
         for (HgSubrepoConfigChange c : repo.getSubrepoConfigChanges(cset)) {
-          fillSubrepoConfigChanges(builder, root, c);
+          fillSubrepoConfigChanges(ctx, builder, root, c);
         }
         attributes.putAll(builder.buildAttributes());
       } catch (Exception e) {
@@ -371,7 +375,8 @@
   }
 
 
-  private void fillSubrepoConfigChanges(@NotNull SubrepoConfigChangesAttributes builder,
+  private void fillSubrepoConfigChanges(@NotNull OperationContext ctx,
+                                        @NotNull SubrepoConfigChangesAttributes builder,
                                         @NotNull HgVcsRoot mainRoot,
                                         @NotNull HgSubrepoConfigChange c) throws URISyntaxException, VcsException {
     List<String> prevRevisions = new ArrayList<String>();
@@ -379,12 +384,12 @@
       String subrepoUrl = c.getCurrent().resolveUrl(mainRoot.getRepository());
       String curRevision = c.getCurrent().revision();
       for (SubRepo prevSubrepo : c.getPrevious()) {
-        prevRevisions.add(prevSubrepo.revision());
+        prevRevisions.add(ctx.getStringFromPool(prevSubrepo.revision()));
       }
       builder.addSubrepoConfigChange(new SubrepoConfigChange(mainRoot)
-              .setSubrepoPath(c.getPath())
-              .setSubrepoRootParamDiff(Constants.REPOSITORY_PROP, subrepoUrl)
-              .setCurrentSubrepoRevision(curRevision)
+              .setSubrepoPath(ctx.getStringFromPool(c.getPath()))
+              .setSubrepoRootParamDiff(Constants.REPOSITORY_PROP, ctx.getStringFromPool(subrepoUrl))
+              .setCurrentSubrepoRevision(ctx.getStringFromPool(curRevision))
               .setPreviousSubrepoRevisions(prevRevisions));
     }
   }
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java	Wed Mar 27 13:45:19 2013 +0400
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/OperationContext.java	Wed Mar 27 13:46:14 2013 +0400
@@ -1,8 +1,10 @@
 package jetbrains.buildServer.buildTriggers.vcs.mercurial;
 
 import com.intellij.openapi.util.Pair;
+import gnu.trove.TLongObjectHashMap;
 import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.AuthSettings;
 import jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot;
+import jetbrains.buildServer.util.Hash;
 import jetbrains.buildServer.util.graph.*;
 import jetbrains.buildServer.vcs.ModificationData;
 import jetbrains.buildServer.vcs.RepositoryStateData;
@@ -30,6 +32,7 @@
   private Map<VcsRootKey, Set<String>> myRevisionsPerRoot = new HashMap<VcsRootKey, Set<String>>();
   private Map<File, ServerHgRepo> myRepos = new HashMap<File, ServerHgRepo>();
   private boolean myIncludeFromRevisions = false;//by default don't include them, they should be included only for subrepos
+  private TLongObjectHashMap<String> myStringPool = new TLongObjectHashMap<String>();
 
   public OperationContext(@NotNull MercurialVcsSupport vcs,
                           @NotNull RepoFactory repoFactory,
@@ -131,6 +134,23 @@
   }
 
 
+  public String getStringFromPool(@Nullable String s) {
+    if (s == null)
+      return null;
+    final long hash = Hash.calc(s);
+    String reused = myStringPool.get(hash);
+    if (reused != null) {
+      if (!reused.equals(s))  // hash collision
+        return s;
+      return reused;
+    }
+    //noinspection RedundantStringConstructorCall
+    reused = new String(s);
+    myStringPool.put(hash, reused);
+    return reused;
+  }
+
+
   /**
    * Collecting changes is per branch, but we should take revisions of other branches
    * into account otherwise plugin can report redundant changes. Consider the following graph: