-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Platform neutral export/import tool was added.
- Loading branch information
1 parent
a375be3
commit 34fa5f8
Showing
1 changed file
with
129 additions
and
0 deletions.
There are no files selected for viewing
129 changes: 129 additions & 0 deletions
129
environment/src/main/java/jetbrains/exodus/env/EnvExportImport.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package jetbrains.exodus.env; | ||
|
||
import jetbrains.exodus.ArrayByteIterable; | ||
|
||
import java.io.*; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.List; | ||
|
||
public class EnvExportImport { | ||
public static void exportEnvironment(Path envPath, EnvironmentConfig envConf, Path exportPath) { | ||
try (Environment env = Environments.newInstance(envPath.toFile(), envConf)) { | ||
env.executeInReadonlyTransaction(txn -> { | ||
if (Files.exists(exportPath)) { | ||
throw new IllegalStateException("Export file already exists: " + exportPath); | ||
} | ||
|
||
Path parent = exportPath.getParent(); | ||
if (parent != null) { | ||
try { | ||
Files.createDirectories(parent); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
try { | ||
Files.createFile(exportPath); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
|
||
try { | ||
try (OutputStream outputStream = Files.newOutputStream(exportPath)) { | ||
try (DataOutputStream dataOutputStream = new DataOutputStream(outputStream)) { | ||
final List<String> stores = env.getAllStoreNames(txn); | ||
|
||
for (String storeName : stores) { | ||
final Store store = env.openStore(storeName, StoreConfig.USE_EXISTING, txn); | ||
|
||
int entryCount = 0; | ||
try (Cursor cursor = store.openCursor(txn)) { | ||
while (cursor.getNext()) { | ||
dataOutputStream.writeUTF(storeName); | ||
dataOutputStream.writeUTF(store.getConfig().name()); | ||
|
||
|
||
byte[] key = cursor.getKey().getBytesUnsafe(); | ||
|
||
dataOutputStream.writeInt(cursor.getKey().getLength()); | ||
dataOutputStream.writeInt(key.length); | ||
dataOutputStream.write(key); | ||
|
||
byte[] value = cursor.getValue().getBytesUnsafe(); | ||
|
||
dataOutputStream.writeInt(cursor.getValue().getLength()); | ||
dataOutputStream.writeInt(value.length); | ||
|
||
dataOutputStream.write(value); | ||
|
||
entryCount++; | ||
} | ||
} | ||
|
||
System.out.println("Exported " + entryCount + " entries from store " + storeName); | ||
} | ||
} | ||
} | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
public static void importEnvironment(Path envPath, EnvironmentConfig envConf, Path importPath) { | ||
try (Environment env = Environments.newInstance(envPath.toFile(), envConf)) { | ||
env.executeInTransaction(txn -> { | ||
try { | ||
try (InputStream inputStream = Files.newInputStream(importPath)) { | ||
try (DataInputStream dataInputStream = new DataInputStream(inputStream)) { | ||
String currentStoreName = null; | ||
Store currentStore = null; | ||
int entryCount = 0; | ||
try { | ||
while (true) { | ||
final String storeName = dataInputStream.readUTF(); | ||
String configName = dataInputStream.readUTF(); | ||
|
||
final StoreConfig storeConfig = StoreConfig.valueOf(configName); | ||
if (currentStoreName == null) { | ||
currentStoreName = storeName; | ||
currentStore = env.openStore(storeName, storeConfig, txn); | ||
} else if (!currentStoreName.equals(storeName)) { | ||
System.out.println("Imported " + entryCount + " entries to store " + currentStoreName); | ||
|
||
currentStoreName = storeName; | ||
currentStore = env.openStore(storeName, storeConfig, txn); | ||
entryCount = 0; | ||
} | ||
|
||
final int keyLength = dataInputStream.readInt(); | ||
final int rawKeyLength = dataInputStream.readInt(); | ||
final byte[] key = new byte[rawKeyLength]; | ||
dataInputStream.readFully(key); | ||
|
||
final int valueLength = dataInputStream.readInt(); | ||
final int rawValueLength = dataInputStream.readInt(); | ||
final byte[] value = new byte[rawValueLength]; | ||
dataInputStream.readFully(value); | ||
|
||
currentStore.put(txn, new ArrayByteIterable(key, keyLength), | ||
new ArrayByteIterable(value, valueLength)); | ||
entryCount += 1; | ||
} | ||
} catch (EOFException e) { | ||
// end of file | ||
} | ||
if (currentStoreName != null) { | ||
System.out.println("Imported " + entryCount + " entries to store " + currentStoreName); | ||
} | ||
} | ||
} | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
}); | ||
} | ||
} | ||
} |