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

Необходимо ускорить копирование. Можно делать не копирование а как-бы линкование файлов
если файловая система поддерживает. Я подобный 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
Zero-copy подход при копировании фотографий
    #40092505
Кажется все просто, Files.createLink() как раз и создает hard link.
...
Рейтинг: 0 / 0
Zero-copy подход при копировании фотографий
    #40092751
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мда.. а ведь есть кейсы когда harkLink не создается. Разные разделы. Надо предусмотреть разные
стратегии копирования. Пускай будет интерфейс.

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

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

}



И в зависимости от того где лежит source и dest - надо автоматом выбирать наилучшую по времени стратегию.
...
Рейтинг: 0 / 0
Zero-copy подход при копировании фотографий
    #40092819
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добавил 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
Zero-copy подход при копировании фотографий
    #40092820
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пофиксил важный баг. Раньше одинаковые 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
Zero-copy подход при копировании фотографий
    #40092821
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Заложен первый кирпичик в поддержку 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
Zero-copy подход при копировании фотографий
    #40092830
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Ожидал что будет прирост в скорости копирования через FileChannel
Не будет.
Будет некоторое уменьшение накладных расходов. На работу с буферами - в том числе.
...
Рейтинг: 0 / 0
Zero-copy подход при копировании фотографий
    #40093328
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Zero-copy подход при копировании фотографий
    #40093344
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделал экспорт метадаты в 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
Zero-copy подход при копировании фотографий
    #40093362
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Формат "оригинальной" даты-времени, допустим, странный. Но почему он странный в других местах?
Вместо "человеко-привычного" (ГГГГ-ММ-ДД чч:мм:сс) - одни сплошные двоеточия.
...
Рейтинг: 0 / 0
Zero-copy подход при копировании фотографий
    #40093397
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вендор запихивает в таком виде. Там вобщем-то поле имеет тип 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
Zero-copy подход при копировании фотографий
    #40095328
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Идея с Graal пока мне не нравится. Бинарник под linux получается размером 50 Мб. Многовато для утилиты.
Хотя я могу его опубликовать. Под Windows я естественно его еще не собирал. Там может быть такая-же
ситуация или еще хуже.

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

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


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