Гость
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Zero-copy подход при копировании фотографий / 12 сообщений из 12, страница 1 из 1
22.08.2021, 12:51
    #40092492
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
В продолжение разработки утилит сортирующих фотки по дате создания снимка.

Необходимо ускорить копирование. Можно делать не копирование а как-бы линкование файлов
если файловая система поддерживает. Я подобный API использовал когда-то давно на С++ под NTFS
но под Java - не делал.

Вот фрагмент кода который в данный момент занят копированием. В настоящий момент копированием занята
глупая и бестолковая однопоточная библиотека apache.commons.io. Первая цель (primary goal) - выкинуть ее и заменить на что-то
более эффективное.


И вторая цель (secondary goal) - исследовать возможности хард и сим-линков на NTFS/ext4 чтобы реализовать zero-copy.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
public class JpegFileVisitor extends SimpleFileVisitor<Path> {


   public static final Pattern JPEG_EXTENSION = Pattern.compile(".+\\.(?<extension>jpg|jfif|jpe|jpeg)$", Pattern.CASE_INSENSITIVE);
   ....
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        String path = file.toAbsolutePath().toString();
        logger.debug("Vizit file path = {}", path);
        Matcher matcher = JPEG_EXTENSION.matcher(path);
        if (matcher.matches()) {
            logger.info("Processing JPEG file {}", path);
            observed++;
            String extension = matcher.group("extension");
            Optional<LocalDateTime> dateTime = jpegDateTimeExtractor.fromFile(new FileInputStream(path), exiftags, dateTimeFormatter);
            if (dateTime.isPresent()) {
                logger.info("Recognized exif tag like a date format '{}'", dateTime.get());
                String syntheticPath = pathFormatter.format(dateTime.get());
                // TODO: This it not a good idea to create folder every time. Should be fixed.
                new File(destDir, FileUtils.cropLastPathElement(syntheticPath)).mkdirs();
                String jpegPath = destDir.getAbsolutePath() + FileUtils.SEPARATOR + syntheticPath + "." + extension;
                logger.debug("Saving to {}",  jpegPath);
                try(InputStream i = new FileInputStream(path);
                    OutputStream o = new FileOutputStream(jpegPath)) {
                    // TODO: Improove performance
                    IOUtils.copy(i, o);
                    processed++;
                }
            } else {
                logger.warn("Unable to detect exif-date attribute set in file {}", path);
                withoutDateInformation++;
                if (trash != null) {
                    logger.debug("Saving into trash path {}", trash.getAbsolutePath());
                    try(InputStream i = new FileInputStream(path);
                        OutputStream o = new FileOutputStream(trash.getAbsolutePath() + FileUtils.SEPARATOR + UUID.randomUUID().toString() + "." + extension)) {
                        // TODO: Improove performance
                        IOUtils.copy(i, o);
                    }
                }
            }
        }
        return FileVisitResult.CONTINUE;
    }
...
Рейтинг: 0 / 0
22.08.2021, 14:30
    #40092505
Zero-copy подход при копировании фотографий
Кажется все просто, Files.createLink() как раз и создает hard link.
...
Рейтинг: 0 / 0
23.08.2021, 17:45
    #40092751
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
Мда.. а ведь есть кейсы когда harkLink не создается. Разные разделы. Надо предусмотреть разные
стратегии копирования. Пускай будет интерфейс.

Код: java
1.
2.
3.
4.
5.
public interface ICopyStrategy {

    void copy(@Nonnull String sourcePath,@Nonnull String destPath) throws IOException;

}



И в зависимости от того где лежит source и dest - надо автоматом выбирать наилучшую по времени стратегию.
...
Рейтинг: 0 / 0
24.08.2021, 01:06
    #40092819
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
Добавил 4 стратегии копирования.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
usage: java -jar photo-time-sort.jar [-c <arg>] -d <arg> [-f <arg>] [-o <arg>] -s <arg> [-t <arg>] [-x <arg>]
 -c,--copystrategy <arg>   Copy-strategy = { DUMMY | FILE_CHANNEL | HARD_LINK | SYM_LINK }. Default = DUMMY
 -d,--dest <arg>           Dest folder
 -f,--timeformat <arg>     Comma-separated local date-time format for exif tag. Default = 'yyyy:MM:dd HH:mm:ss'
 -o,--outformat <arg>      Output folder format. Default = 'yyyy/MM/dd/HH-mm-ss'
 -s,--source <arg>         Source jpeg files folder
 -t,--trash <arg>          Unrecognized files
 -x,--exiftags <arg>       Comma-separated exif-tags list. Default = 'DateTime,DateTimeOriginal,DateTimeDigitized'



Ожидал что будет прирост в скорости копирования через FileChannel между двумя разными физическими дисками.
Но пока незаметно.

Последняя стратегия интересна тем что можно в листинге восстановить оригинальные имена.

Код: java
1.
2.
3.
4.
5.
6.
7.
$ ls -lF
drwxrwxr-x 2 mayton mayton 326 Aug 24 00:57 ./
drwxrwxr-x 7 mayton mayton  80 Aug 24 00:57 ../
lrwxrwxrwx 1 mayton mayton  42 Aug 24 00:57 14-54-30.JPG -> /bigdata/foto/2019-Sep-Odessa/SAM_6124.JPG
lrwxrwxrwx 1 mayton mayton  42 Aug 24 00:57 17-35-44.JPG -> /bigdata/foto/2019-Sep-Odessa/SAM_6125.JPG
lrwxrwxrwx 1 mayton mayton  42 Aug 24 00:57 17-35-54.JPG -> /bigdata/foto/2019-Sep-Odessa/SAM_6126.JPG
lrwxrwxrwx 1 mayton mayton  42 Aug 24 00:57 17-36-27.JPG -> /bigdata/foto/2019-Sep-Odessa/SAM_6127.JPG



Под Windows симлинки скорее всего не работают. Я пока тестирую на Linux.

Так что ребята-виндузятники где вы. Тестируйте что и как.
...
Рейтинг: 0 / 0
24.08.2021, 01:09
    #40092820
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
Пофиксил важный баг. Раньше одинаковые HH-mm-ss в файле переписывали дважды одну и ту-же
картинку если секунды фотосъемки совпадали. Сейчас этого не будет. К файлам будет добавляться
уникальный счетчик типа целого числа в скобках:

Код: java
1.
2.
lrwxrwxrwx 1 mayton mayton 62 Aug 24 00:57 '04-25-29(1).JPG'
lrwxrwxrwx 1 mayton mayton 73 Aug 24 00:57  04-25-29.JPG 
...
Рейтинг: 0 / 0
24.08.2021, 01:20
    #40092821
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
Заложен первый кирпичик в поддержку COW для некоторых Linux платформ. Но это уже экзотика.
Java напрямую не поддерживает такой API. Я буду думать как его вызвать косвенно. Кроме
того этот метод поддерживают не все файловые системы. У меня на бэкапном диске стоит XFS
и это дает возможность протестировать. Обычные (дефолтные) файловые системы (ext4)
не поддерживают пока эту фичу.

Обычным копированием толстых файлов (blue-ray фильмов) я субъективно замечаю что
физического копирования действительно не просиходит

Код: java
1.
cp --reflink ....



работает мгновенно.

Интерфейс я немножко расширил добавив специальные ограничители. Например класс ФС и ОС.
Например софтлинки на файлы в NTFS не существовали (по крайней мере до Windows7) и поэтому
нет смысла юзать неподходящие стратегии.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
public class CopyOnWriteCopyStrategy implements ICopyStrategy {

    @Nullable
    @Override
    public Set<String> applicableToOs() {
        return Set.of("linux");
    }

    @Nullable
    @Override
    public Set<String> applicableToFileSystems() {
        return Set.of("xfs", "btrfs");
    }

    @Override
    public void copy(@Nonnull String sourcePath, @Nonnull String destPath) throws IOException {
        // TODO: $ cp --reflink=auto sourcePath destPath
        throw new RuntimeException("Not implemented yet!");
    }
}
...
Рейтинг: 0 / 0
24.08.2021, 06:46
    #40092830
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
mayton
Ожидал что будет прирост в скорости копирования через FileChannel
Не будет.
Будет некоторое уменьшение накладных расходов. На работу с буферами - в том числе.
...
Рейтинг: 0 / 0
26.08.2021, 18:26
    #40093328
вадя
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
...
Рейтинг: 0 / 0
26.08.2021, 20:48
    #40093344
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
Сделал экспорт метадаты в json для поисков и анализа. Может кто-то захочет поискать фотки определенного разрешения
или снятых каким-то аппаратом. Есть также сведенья по GPS. Правда среди моих фоток это были редкие
экземпляры. Возможно принесенные мной откуда-то извне.

Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
 {
  "Path" : "/bigdata/foto/100_FUJI/DSCF0582.JPG",
  "ImageMetadata" : {
    "TiffFields" : {
      "Make" : "FUJIFILM",
      "Model" : "FinePix JX300",
      "XResolution" : "72",
      "YResolution" : "72",
      "Software" : "Digital Camera FinePix JX300 Ver1.00",
      "DateTime" : "2011:07:01 01:02:55",
      "ExifOffset" : 290,
      "ExposureTime" : "10/100 (0.1)",
      "FNumber" : "260/100 (2.6)",
      "DateTimeOriginal" : "2011:07:01 01:02:55",
      "DateTimeDigitized" : "2011:07:01 01:02:55",
      "CompressedBitsPerPixel" : "4",
      "ApertureValue" : "276/100 (2.76)",
      "MaxApertureValue" : "276/100 (2.76)",
      "FocalLength" : "5",
      "ExifImageWidth" : 2048,
      "ExifImageLength" : 1536,
      "InteropOffset" : 25600,
      "FocalPlaneXResolution" : "3,339",
      "FocalPlaneYResolution" : "3,339",
      "InteroperabilityIndex" : "R98",
      "XResolution" : "72",
      "YResolution" : "72",
      "JpgFromRawStart" : 25764,
      "JpgFromRawLength" : 1821
    }
  }
}
...
Рейтинг: 0 / 0
27.08.2021, 05:27
    #40093362
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
Формат "оригинальной" даты-времени, допустим, странный. Но почему он странный в других местах?
Вместо "человеко-привычного" (ГГГГ-ММ-ДД чч:мм:сс) - одни сплошные двоеточия.
...
Рейтинг: 0 / 0
27.08.2021, 10:29
    #40093397
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
Вендор запихивает в таком виде. Там вобщем-то поле имеет тип ASCII. Поэтому так чудно и выглядит.

Код: java
1.
2.
3.
4.
$ exif  /bigdata/foto/100_FUJI/DSCF0582.JPG  | grep Date
Date and Time       |2011:07:01 01:02:55
Date and Time (Origi|2011:07:01 01:02:55
Date and Time (Digit|2011:07:01 01:02:55
...
Рейтинг: 0 / 0
05.09.2021, 11:09
    #40095328
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Zero-copy подход при копировании фотографий
Идея с Graal пока мне не нравится. Бинарник под linux получается размером 50 Мб. Многовато для утилиты.
Хотя я могу его опубликовать. Под Windows я естественно его еще не собирал. Там может быть такая-же
ситуация или еще хуже.

Другая идея - перенести это в scala-native. Там будет другой бак-енд компиллятор. И может там он не будет
тащить с собой весь rt.

Правда мне придется сменить язык разработки.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Zero-copy подход при копировании фотографий / 12 сообщений из 12, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]