Skip to content

Commit

Permalink
Оптимизировал расход памяти в тестах
Browse files Browse the repository at this point in the history
  • Loading branch information
demidko committed Sep 18, 2021
1 parent 437a8a7 commit 80db07b
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 11 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Java библиотека для быстрого (!) получения лем

[![](https://jitpack.io/v/demidko/aot.svg)](https://jitpack.io/#demidko/aot)

## Пример
## Как использовать?

```java
import static java.lang.System.out;
Expand All @@ -27,15 +27,15 @@ class Example {

public static void main(String[] args) {
var meanings = lookupForMeanings("люди");

out.println(meanings.size());
/* 1 */
/* 1 */

out.println(meanings.get(0).getMorphology());
/* [С, мр, им, мн] */
/* [С, мр, им, мн] */

out.println(meanings.get(0).getLemma());
/* человек */
/* человек */

for (var t : meanings.get(0).getTransformations()) {
out.println(t.toString() + " " + t.getMorphology());
Expand Down Expand Up @@ -105,7 +105,7 @@ class Example {
наконец, третий смысл, это вторая лемма, замокнуть (он что сделал? Он замок под дождем). Для нее
слово замок характеризуется лишь одним набором грамматической информации.

## Источник данных
## Откуда данные?

Используется словарь бинарной морфологии из
проекта [aot-binary](https://github.com/demidko/aot-binary).
Expand Down
101 changes: 101 additions & 0 deletions src/main/java/com/github/demidko/aot/BitReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.github.demidko.aot;

import static java.util.BitSet.valueOf;

import java.util.BitSet;

/**
* Класс предназначен для побитового чтения из примитивов
*/
public class BitReader {

private final BitSet bs;
private int pos = -1;

public BitReader(long... n) {
bs = valueOf(n);
}

public BitReader(byte... b) {
bs = valueOf(b);
}

public BitReader(BitReader other) {
bs = (BitSet) other.bs.clone();
pos = other.pos;
}

/**
* @return метод читает следующий по порядку бит
*/
public boolean readBit() {
return bs.get(++pos);
}

/**
* Метод читает следующие N бит по порядку
*
* @param size количество бит
* @return биты сохраненные в длинное целое число
*/
public long readLong(int size) {
BitWriter w = new BitWriter();
for (int i = 0; i < size; ++i) {
w.write(readBit());
}
return w.toLong();
}

/**
* @return прочитать следующее длинное целое
*/
public long readLong() {
return readLong(64);
}

/**
* Метод читает следующие N бит по порядку
*
* @param size количество бит
* @return биты сохраненные в целое число
*/
public int readInt(int size) {
return (int) readLong(size);
}

/**
* @return прочитать следующее целое
*/
public int readInt() {
return readInt(32);
}


/**
* Метод читает следующие N бит по порядку
*
* @param size количество бит
* @return биты сохраненные в короткое целое число
*/
public short readShort(int size) {
return (short) readLong(size);
}

public short readShort() {
return readShort(16);
}

/**
* Метод читает следующие N бит по порядку
*
* @param size количество бит
* @return биты сохраненные в байт
*/
public byte readByte(int size) {
return (byte) readLong(size);
}

public byte readByte() {
return readByte(8);
}
}
88 changes: 88 additions & 0 deletions src/main/java/com/github/demidko/aot/BitWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.github.demidko.aot;

import static java.util.BitSet.valueOf;

import java.util.BitSet;

/**
* Класс предназначен для побитовой записи в примитивы
*/
public class BitWriter {

private final BitSet bs;
private int pos = -1;

public BitWriter(byte... b) {
bs = valueOf(b);
}

public BitWriter(long... l) {
bs = valueOf(l);
}

public BitWriter() {
this(new byte[8]);
}

public BitWriter(BitWriter other) {
bs = (BitSet) other.bs.clone();
pos = other.pos;
}

/**
* Метод записывает следующий по порядку бит
*/
public void write(boolean bit) {
bs.set(++pos, bit);
}

/**
* Метод сохраняет результат записи в long
*
* @return результат записи
*/
public long toLong() {
return bs.toLongArray().length == 0 ? 0 : bs.toLongArray()[0];
}

public int toInt() {
return (int) toLong();
}

public short toShort() {
return (short) toLong();
}

public byte toByte() {
return (byte) toLong();
}

/**
* Метод записывает по порядку заданное количество бит
*
* @param bits набор бит
* @param len количество бит из набора
*/
public void write(long bits, int len) {
BitReader r = new BitReader(bits);
for (int i = 0; i < len; ++i) {
write(r.readBit());
}
}

public void writeLong(long l) {
write(l, 64);
}

public void writeInt(int i) {
write(i, 32);
}

public void writeShort(short s) {
write(s, 16);
}

public void writeByte(byte b) {
write(b, 8);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.util.ListIterator;

/**
* Чтобы не копировать лишний раз массивы
* Класс позволяет создать список меньшего размера, на основе массива большего размера, без копирования.
*/
class ImmutableList<T> implements List<T> {

Expand Down
32 changes: 30 additions & 2 deletions src/main/java/com/github/demidko/aot/WordformMeaning.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ public class WordformMeaning {
* нужно использовать {@link WordformMeaning#getDictionary()}.
*/
private static HashDictionary dictionary;

private final int lemmaId;

private final int flexionIndex;

private WordformMeaning(int lemmaId, int flexionIndex) {
Expand All @@ -31,7 +33,19 @@ private WordformMeaning(int lemmaId, int flexionIndex) {
}

/**
* @return Исходная текстовая запись слова (может быть общей с другими смыслами, напр. "замок" и "замок").
* @return Уникальный идентификатор, по которому можно восстановить словоформу, даже после перезапуска приложения.
* Идентификатор состоит из 48 бит (32 бита индекс леммы, 16 бит смещение трансформации) записанных по порядку в
* long.
*/
public long getId() {
BitWriter w = new BitWriter();
w.write(lemmaId, 4);
w.write(flexionIndex, 4);
return w.toLong();
}

/**
* @return Текстовая запись слова (может быть общей с другими смыслами, напр. "замок" и "замок").
*/
@Override
public String toString() {
Expand Down Expand Up @@ -80,9 +94,23 @@ public static List<WordformMeaning> lookupForMeanings(String w) throws IOExcepti
}

/**
* @param id идентификатор полученный ранее при помощи {@link WordformMeaning#getId()}
* @return словоформа смысла
*/
public static WordformMeaning lookupForMeaningById(long id) throws IOException {
BitReader reader = new BitReader(id);
int lemmaId = reader.readInt();
int flexionIndex = reader.readShort();
getDictionary();
return new WordformMeaning(lemmaId, flexionIndex);
}

/**
* Инициализация {@link WordformMeaning#dictionary}
*
* @return словарь лемм и морфологии (низкоуровневое API)
*/
private static HashDictionary getDictionary() throws IOException {
static HashDictionary getDictionary() throws IOException {
if (dictionary == null) {
dictionary = new HashDictionary();
}
Expand Down
5 changes: 3 additions & 2 deletions src/test/java/com/github/demidko/aot/HashDictionaryTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.demidko.aot;

import static com.github.demidko.aot.WordformMeaning.getDictionary;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
Expand All @@ -12,11 +13,11 @@

public class HashDictionaryTest {

private static HashDictionary d = null;
private static HashDictionary d;

static {
try {
d = new HashDictionary();
d = getDictionary();
} catch (IOException e) {
e.printStackTrace();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.io.IOException;
import java.util.List;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;


Expand Down

0 comments on commit 80db07b

Please sign in to comment.