[log] IDEA-132229 Optimize HashImpl serialization

* Read/write bytes, don't convert from/to String.
* Introduce VcsLogHashMap versioning, cleanup previous version on start.
This commit is contained in:
Kirill Likhodedov
2014-11-11 14:31:28 +03:00
parent 7368174a74
commit 4e077068bf
3 changed files with 98 additions and 5 deletions
@@ -54,18 +54,24 @@ public class VcsLogHashMap implements Disposable {
private static final File LOG_CACHE_APP_DIR = new File(PathManager.getSystemPath(), "vcs-log");
private static final Logger LOG = Logger.getInstance(VcsLogHashMap.class);
private static final int VERSION = 1;
private final PersistentEnumerator<Hash> myPersistentEnumerator;
VcsLogHashMap(@NotNull Project project, @NotNull Map<VirtualFile, VcsLogProvider> logProviders) throws IOException {
final File myMapFile = new File(LOG_CACHE_APP_DIR, calcLogId(project, logProviders));
String logId = calcLogId(project, logProviders);
final File mapFile = new File(LOG_CACHE_APP_DIR, logId + "." + VERSION);
if (!mapFile.exists()) {
IOUtil.deleteAllFilesStartingWith(new File(LOG_CACHE_APP_DIR, logId));
}
Disposer.register(project, this);
myPersistentEnumerator = IOUtil.openCleanOrResetBroken(new ThrowableComputable<PersistentEnumerator<Hash>, IOException>() {
@Override
public PersistentEnumerator<Hash> compute() throws IOException {
return new PersistentEnumerator<Hash>(myMapFile, new MyHashKeyDescriptor(), Page.PAGE_SIZE);
return new PersistentEnumerator<Hash>(mapFile, new MyHashKeyDescriptor(), Page.PAGE_SIZE);
}
}, myMapFile);
}, mapFile);
}
@NotNull
@@ -189,12 +195,12 @@ public class VcsLogHashMap implements Disposable {
private static class MyHashKeyDescriptor implements KeyDescriptor<Hash> {
@Override
public void save(@NotNull DataOutput out, Hash value) throws IOException {
out.writeUTF(value.asString());
((HashImpl)value).write(out);
}
@Override
public Hash read(@NotNull DataInput in) throws IOException {
return HashImpl.build(in.readUTF());
return HashImpl.read(in);
}
@Override
@@ -15,9 +15,13 @@
*/
package com.intellij.vcs.log.impl;
import com.intellij.util.io.DataInputOutputUtil;
import com.intellij.vcs.log.Hash;
import org.jetbrains.annotations.NotNull;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Arrays;
/**
@@ -37,6 +41,19 @@ public class HashImpl implements Hash {
return new HashImpl(data);
}
@NotNull
public static Hash read(@NotNull DataInput in) throws IOException {
int length = DataInputOutputUtil.readINT(in);
byte[] buf = new byte[length];
in.readFully(buf);
return new HashImpl(buf);
}
public void write(@NotNull DataOutput out) throws IOException {
DataInputOutputUtil.writeINT(out, myData.length);
out.write(myData);
}
@NotNull
private static byte[] buildData(@NotNull String inputStr) {
// if length == 5, need 3 byte + 1 signal byte
@@ -0,0 +1,70 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.vcs.log.impl;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.io.DataOutputStream;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import java.io.*;
import static org.junit.Assert.assertEquals;
public class HashSerializeTest {
@Test
public void full_hash() throws IOException {
HashImpl hash = (HashImpl)HashImpl.build("d35ee91fad4a04bce0ea91a762cc8f3bf3e1929f");
File file = writeToTempFile(hash);
HashImpl newHash = readFromFile(file);
assertEquals(hash, newHash);
}
@Test
public void short_hash() throws IOException {
HashImpl hash = (HashImpl)HashImpl.build("d35ee91");
File file = writeToTempFile(hash);
HashImpl newHash = readFromFile(file);
assertEquals(hash, newHash);
}
@NotNull
private static File writeToTempFile(@NotNull HashImpl hash) throws IOException {
File file = FileUtil.createTempFile("", "");
DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
try {
hash.write(out);
}
finally {
out.close();
}
return file;
}
@NotNull
private static HashImpl readFromFile(@NotNull File file) throws IOException {
HashImpl newHash;
DataInputStream in = new DataInputStream(new FileInputStream(file));
try {
newHash = (HashImpl)HashImpl.read(in);
}
finally {
in.close();
}
return newHash;
}
}