Хорошо, круто, вы используете это как возможность продемонстрировать Clojure.Итак, вы хотите продемонстрировать FP и параллелизм.Подумайте об этом.
Чтобы удивить ваших собеседников, я хотел бы продемонстрировать:
- Производительность вашей программы с использованием одного потока.
- Как увеличивается производительность вашей программыпо мере увеличения количества потоков.
- Как легко перевести вашу программу из однопоточной в многопоточную.
Вы можете создать функцию для выгрузки одной таблицы вXML-файл.
(defn table-to-xml [name] ...)
С этим вы можете решить весь или свой код для основной задачи преобразования ваших реляционных данных в XML.
Теперь, когда вы решили основную проблему, посмотритеесли добавление большего количества потоков увеличит вашу скорость.
Вы можете изменить table-to-xml
, чтобы принять дополнительный параметр:
(defn table-to-xml [name thread-count] ...)
Это означает, что у вас есть n потоков, работающих на одной таблице.В этом случае каждый поток может обрабатывать каждую n-ю строку.Проблема размещения нескольких потоков в одной таблице состоит в том, что каждый поток захочет записать в один и тот же XML-файл.Это узкое место может сделать стратегию бесполезной, но ее стоит попробовать.
Если приемлемо создание одного XML-файла на таблицу, то порождение одного потока на таблицу может быть легким выигрышем.
(map #(future (table-to-xml %)) (table-names))
Используя только взаимно-однозначные отношения между таблицами, файлами и потоками: в качестве руководства, я бы ожидал, что ваш код не будет содержать никаких ссылок или досинксов, и решение должно быть довольно простым.
Как только выначните создавать несколько потоков для каждой таблицы, к которой вы добавляете сложность и, возможно, не увидите значительного увеличения производительности.
В любом случае вам, вероятно, потребуется один или два запроса на таблицу для получения значений и метаданных.Относительно вашего комментария о нежелании загружать все данные в память: каждый поток будет обрабатывать только одну строку за раз.
Надеюсь, это поможет!
Учитывая ваш комментарий, вот некоторые псевдо-ишкод, который может помочь:
(defn write-to-xml [person]
(dosync
(with-out-append-writer *path*
(print-person-as-xml))))
(defn resolve-relation [person table-name one-or-many]
(let [result (query table-name (:id person))]
(assoc person table-name (if (= :many one-or-many)
result
(first result)))))
(defn person-to-xml [person]
(write-to-xml
(-> person
(resolve-relation "phones" :many)
(resolve-relation "addresses" :many))))
(defn get-people []
(map convert-to-map (query-db ...)))
(defn people-to-xml []
(map (fn [person]
(future (person-to-xml %)))
(get-people)))
Вы можете использовать библиотеку исполнителей Java для создания пула потоков.