Xodus создает огромный файл при переходе от значения ключа (окружение) к реляционному (сущность) - PullRequest
0 голосов
/ 17 февраля 2020

Первоначально я создал базу данных значений ключей с помощью Xodus Entity, которая создала небольшую базу данных объемом 2 ГБ:

public static void main(String[] args) throws Exception{

        if (args.length != 2){
            throw new Exception("Argument missing. Current number of arguments: " + args.length); 
        }

        long offset = Long.parseLong(args[0]);
        long chunksize = Long.parseLong(args[1]);

        Path pathBabelNet = Paths.get("/mypath/BabelNet-API-3.7/config");
        BabelNetLexicalizationDataSource dataSource = new BabelNetLexicalizationDataSource(pathBabelNet);
        Map<String, List<String>> data = new HashMap<String, List<String>>();
        data = dataSource.getDataChunk(offset, chunksize);

        jetbrains.exodus.env.Environment env = Environments.newInstance(".myAppData");
        final Transaction txn = env.beginTransaction();
        Store store = env.openStore("xodus-lexicalizations", StoreConfig.WITHOUT_DUPLICATES, txn);

        for (Map.Entry<String, List<String>> entry : data.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue().get(0);

            store.put(txn, StringBinding.stringToEntry(key), StringBinding.stringToEntry(value));
        }

        txn.commit();
        env.close();

    }

Я использовал пакетный сценарий, чтобы сделать это в виде кусков:

#!/bin/bash

START_TIME=$SECONDS

chunksize=50000

for ((offset=0; offset<165622128;))
do
    echo $offset;
    java -Xmx10g -jar /path/to/jar.jar $offset $chunksize
    offset=$((offset+(chunksize*12)))
done

ELAPSED_TIME=$(($SECONDS - $START_TIME))

echo $ELAPSED_TIME;

Теперь я изменил его так, чтобы он был реляционным:

public static void main(String[] args) throws Exception{

        if (args.length != 2){
            throw new Exception("Argument missing. Current number of arguments: " + args.length); 
        }

        long offset = Long.parseLong(args[0]);
        long chunksize = Long.parseLong(args[1]);

        Path pathBabelNet = Paths.get("/mypath/BabelNet-API-3.7/config");
        BabelNetLexicalizationDataSource dataSource = new BabelNetLexicalizationDataSource(pathBabelNet);
        Map<String, List<String>> data = new HashMap<String, List<String>>();
        data = dataSource.getDataChunk(offset, chunksize);

        PersistentEntityStore store = PersistentEntityStores.newInstance("lexicalizations-test");
        final StoreTransaction txn = store.beginTransaction(); 

        Entity synsetID;
        Entity lexicalization;
        String id;

        for (Map.Entry<String, List<String>> entry : data.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue().get(0);

            synsetID = txn.newEntity("SynsetID");
            synsetID.setProperty("synsetID", key);

            lexicalization = txn.newEntity("Lexicalization");
            lexicalization.setProperty("lexicalization", value);

            lexicalization.addLink("synsetID", synsetID);
            synsetID.addLink("lexicalization", lexicalization);

            txn.flush();
        }

        txn.commit();
    }

И это создало файл размером более 17 ГБ, и он остановился только потому, что у меня не хватило памяти. Я понимаю, что он будет больше, потому что он должен хранить ссылки, между прочим, но в десять раз больше? Что я делаю не так?

1 Ответ

1 голос
/ 19 февраля 2020

По какой-то причине удаление txn.flush() исправляет все. Теперь это всего 5,5 ГБ.

...