powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Тяпничная huge-сортировка
25 сообщений из 133, страница 3 из 6
Тяпничная huge-сортировка
    #39417723
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonkealon(Ruslan)делал такую задачку так (в принципе, классическая схема):
читал блоками по установленному лимиту

сортировал блок (QSort) и сохранял в файл

дальше над блоками обычная сортировка слияниями(объединение равноценных блоков)


В 2003-м я делал это на C# с XML документами. Но постановка была посложнее
т.к сложно было оценить сколько XML-records загонять в 1 блок и сервер периодически
падал. А XMLReader не обладал API для подсчета символов. Вобщем делал partitions
на глаз. По количеству тегов.
SAX в этом случае надо бы использовать - обычно у этих парсеров есть поблочное добавление RAW данных, которые собственно и лимитируешь
ну а периодические падения окружения, наверное, не должны включаться в условие тестового задания

или это реальная задача?
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417726
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevЕдинственный выигрыш - возможная компрессия. Но если диски сильно медленнее CPU, то тогда достаточно жать временные файлы максимального эффективными алгоритмами (a la LZW) и нафиг какой-то свой самопал.

Про компрессию я упоминал выше одобрительно. Но лучше без LZW. Для объемов
которыми оперирует big-data нам достаточно хотя-бы поджать дубли и это уже
будет огромный плюч к самой процедуре merge.

А LZW на больших объемах теряет эффективность особенно когда после 50% файла
меняется кодировка или энтропия потока. LZW уже не может перестроить справочник
и становится балластом.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417728
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)maytonпропущено...

В 2003-м я делал это на C# с XML документами. Но постановка была посложнее
т.к сложно было оценить сколько XML-records загонять в 1 блок и сервер периодически
падал. А XMLReader не обладал API для подсчета символов. Вобщем делал partitions
на глаз. По количеству тегов.
SAX в этом случае надо бы использовать - обычно у этих парсеров есть поблочное добавление RAW данных, которые собственно и лимитируешь
ну а периодические падения окружения, наверное, не должны включаться в условие тестового задания

или это реальная задача?
XMLReader не виноват. Собственно это почти и есть SAX если посмотреть на его юзкейсы.
И память не он потреблял а коллекция куда я складывал теги перед тем как подать их
на вход QuickSort.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417729
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Такую задачу не делал, т.к. было не нужно.

И стандартными методами (СУБД) данные в единицы / сотни Гигабайт обрабатывались вполне нормальное время. Подождать десяток секунд - минута для сортировки реальных данных 8 Gb в банальном PostgreSQL - не проблема.

Программно (JDBC) переливал в многопотоке данные под сотни Гб, но и там, за пару часов все вполне себе строилось )))

Работал с БД в 15 Tb, но она крутились на железке с дисками FC и со скоростью full scan в 2-4 Gb в секунду )))
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417733
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevЯ бы все таки определился, что такое "текстовый". И что такое "строка"

Т.к. предыдущий похожий топик предполагал, что может быть и строка размером в гигабайты... а тогда говорить о префиксах, деревьях совершенно мозги вскипают.

Предлагаю понятие строка, в ТЗ хотя бы 256 или пусть даже 1024 символами ограничить. А то ТЗ, совершенно не ТЗ )))

Я согласен. Нам сложно будет вычислять разрядность смещения если не знаем какая длина строки. Зайдем в тупик нахер...

Давайте обсудим. ИМХО 256 - это маловато. Кажется у меня есть исходники
в которых длина строки поболее.

Вот 64K символов это уже ближе к реалу. Вроде как длина сегментика. Или близко к Oracle VARCHAR2(32000).

Или можно в 4Гига. Вроде как уже ограничение 32х битной машинки.

Вобщем скажите ваше имхо.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417738
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Леонид, забегая вперед я скажу что штатная тулза от windows
уже умеет смотреть в temp но я не ищу легких путей. Я ставлю сверх
задачи с оптимизациями которые штатные утилиты скорее всего (99%)
проигнорировали.
Код: sql
1.
2.
3.
4.
5.
6.
  /T[EMPORARY]

    [диск2:][путь2]           Определяет путь к папке, содержащей рабочие
                              файлы сортировки, в том случае, когда данные
                              не помещаются в основной памяти. По умолчанию
                              используется системная временная папка.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417740
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonДля объемов
которыми оперирует big-data нам достаточно хотя-бы поджать дубли и это уже
будет огромный плюч к самой процедуре merge.

а настолько ли это критично и какое железо / данные.

А тогда возникает вопрос, насколько все "пляски с бубном" это могут ускорить? На 20-30%, на 50%... А это спасет "отца русской демократии"?
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417743
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevПредположим, что у нас huge файл 1 Tb и 1 Gb RAM. Буфер IO пусть 64 Mb, тогда одновременно сливаем до 16 файлов.

Первый проход по диску (разлияние + сортировка) - чтение 1 Tb и запись 1024 отсортированных частей
Второй проход 1024 / 16 = 64
Третий проход 64 / 16 = 4
Четвертый проход - завершили обработку

Честно говоря я не очень понял твою арифметику. Сколько-бы у тебя буферов не стояло,
ты не можешь превысить паспортную скорость канала взаимодействия c HDD.

Тоесть в прямом (direct) алгоритме сортировки слиянием с 1 Tb HDD, 1 Gb RAM.
Мы делаем
1) 1024 partitions, и столько-же quick-sorts
2) 512 merges 1+1 = 1
3) 256 merges
4) 128
5) 64
6) 32
7) 16
8) 8
9) 4
10) 2
11) Алгоритм завершен. Мы получили отсортированный терабайт.

(в скобках замечу что требуется дополнительная дисковая память)

Далее. Я опираюсь на инженерное предположение что файл не всегда лежит на HDD/SDD.
Он может лежать на абстрактных устройствах с ярко выраженным последовательным
доступом WebDav/HTTP, и вообще я считаю что устройства последовательног доступа
сокеты, каналы передачи данных, и даже жлобские unixoвые stdin/stdout
всегда были есть и будут неотъемлемым элементом It-вселенной.

Поэтому Я и старина Кнут могут не беспокоится по поводу девальвации
алгорима. Он по прежнему будет востребован. Хотя и не так сильно
как в эпоху магнитных лент и перфолент.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417746
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevmaytonДля объемов
которыми оперирует big-data нам достаточно хотя-бы поджать дубли и это уже
будет огромный плюч к самой процедуре merge.

а настолько ли это критично и какое железо / данные.

А тогда возникает вопрос, насколько все "пляски с бубном" это могут ускорить? На 20-30%, на 50%... А это спасет "отца русской демократии"?
Ну представь себе график. Типа по горизонтали эффективность алгоритма (в нашем
случае пропускная способность в строках) а по вертикали - complexity алгоиима.

Так вот. Если мы просто включим RLE, или подсчет повторов строк - это даст
+10% к сложности алгоритма мержа. И с другой стороны даст х..й его знает
сколько эффективности. Может 0%. А может 1000%. Все зависит от числа дублей
в файле.

Стоит ли игра свеч? ХЗ. Я считаю что при включении этого жлобского RLE - стоит.
На графике будет резкий излом.

А вот LZW я-бы уже не включал. Просто мне так кааааатся.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417754
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЧестно говоря я не очень понял твою арифметику. Сколько-бы у тебя буферов не стояло,
ты не можешь превысить паспортную скорость канала взаимодействия c HDD.
...
11) Алгоритм завершен. Мы получили отсортированный терабайт.

Да. Классический. Работающий на чисто последовательной магнитной ленте (3 штуки).

Но если магнитных лент не 3, а больше - то никто не мешает за один шаг обработки сразу делать merge нескольких файлов.

Т.к. доступ к HDD, а тем более к SSD, все же НЕ "ярко выраженный последовательный", то никто не мешает на HDD, а тем более SSD (!) мерж выполнять за значительно меньшее число проходов.

maytonДалее. Я опираюсь на инженерное предположение что файл не всегда лежит на HDD/SDD.
Он может лежать на абстрактных устройствах с ярко выраженным последовательным
доступом WebDav/HTTP, и вообще я считаю что устройства последовательног доступа
....
Файл или ВРЕМЕННЫЕ файлы?

Конечно, можно и swap на WebDav / HTTP положить, но нужно ли и насколько часто это требуется?
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417764
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevНо если магнитных лент не 3, а больше - то никто не мешает за один шаг обработки сразу делать merge нескольких файлов.

Т.к. доступ к HDD, а тем более к SSD, все же НЕ "ярко выраженный последовательный", то никто не мешает на HDD, а тем более SSD (!) мерж выполнять за значительно меньшее число проходов.

Я не очень понимаю зачем ты так зацепился за SSD.

Ну ОК. Давай так. Две опции алгоритма. Первый летает по классической схеме которую я описал.
А второй попробуй реализовать сам опираясь на свойства SDD.
Код: sql
1.
$ hugesort --hdd  ...



Код: sql
1.
$ hugesort --sdd  ...
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417769
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЯ не очень понимаю зачем ты так зацепился за SSD.

Я зацепился за сферичность задачи.

Можно обсуждать сферичную сортировку, но обсуждать сферичную ОПТИМАЛЬНУЮ сортировку - это уже за гранью добра и зла.

Т.к. понятие оптимальности будут разные. Особенно если мы говорим про ОПТИМИЗАЦИЮ. Магнитные ленты это одно, RAM это другое, SSD где-то посередине.

Ээээх!... Давай....

Только у меня на домашнем компе с местом не все хорошо. 20 Gb на SSD, 100 Gb на Seagate + есть WD Green. Пошел запускать Eclipse.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417773
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevmaytonЯ не очень понимаю зачем ты так зацепился за SSD.

Я зацепился за сферичность задачи.
И не говори. Чортов Microsoft. Поубивать бы таких собеседователей... Мдя.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417833
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsevmaytonпропущено...

В моей терминологии это triplet. Тройка. Потому-что две вершины - это как-бы каналы
чтения. И одна вершина - это канал записи.
Почему две вершины?

Насколько я помню Кнута (читал лет 25 назад!), кол-во каналов чтения предлагалось выбирать по кол-ву устройств. Если брать современных SDD / HDD, то грубо говоря, кол-во RAM / размер буфера выделенного для последовательного много блочного чтения/записи.
ИМХО дерево из триплетов эффективнее. Закэшировал в триплите минимальный из 2-х, забрали, закэшировал следующий и т.д.
А если все входы собрать в один массив, то каждый раз скан всех входов в поисках минимального.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417846
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
парни, задача тестовая и обычно для системщиков

ограничения обычно на RAM - пусть мегабайт, два; длина строки путь до 256 - 1000 символов, диски абсолютно неизвестный (но памяти там с большим запасом)

нравится это или нет, все вопли и фантазии про SQL сервер и пр., которые что-то могут - не в тему. То что могут выжать такого рода системы относится к другим вопросам и задаются другим людям.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417850
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИМХО дерево из триплетов эффективнее.
Вот с этого момента - непонятно.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417856
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonDima TИМХО дерево из триплетов эффективнее.
Вот с этого момента - непонятно.
Что такое слияние сортированных последовательностей:
берем головы последовательностей, т.е. первый элемент каждой и выбираем минимальный, его отправляем на выход, в той последовательности из которой он был берем следующий и так по кругу пока все элементы не кончатся.

Если у нас N последовательностей, то каждый проход N-1 сравнений.

Если дерево то log 2 (N), т.к. верхний триплет извлекая элемент со входа заставляет извлечь следующий элемент только один нижестоящий триплет и т.д. по цепочке.

Тут накладные расходы памяти на создание триплетов, но при ограничении минимального размера последовательности (меньше минимума обычная сортировка) такая сортировка может и взлететь.

В случае с твоим биг-файлом это два чтения исходного файла: первый проход инициализация триплетов, второй запись результата.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417885
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ладно. Беру рекламную паузу. Вечером нарисую картинку.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39417898
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В принципе можно без сортировок, на одних триплетах:

Делаем максимально возможное дерево, заполняем все триплеты, если дерево наполнилось, то делаем слив меньшего по размеру поддерева во временный файл, перестраиваем дерево, ставим файл на вход как источник последовательности и снова продолжаем наполнять дерево.

Как все последовательности вошли в дерево - слив результата.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39418133
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут можно взять файлик для тестов 1.2 Гб неупорядоченного текста, местами сортированного.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39418153
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T.....
А если все входы собрать в один массив, то каждый раз скан всех входов в поисках минимального.
Да хоть по сто раз скан всех входов...

Разница скана в RAM и доступ к диску/ленте - не порядки, а несколько порядков (тысячи, десятки тысяч раз, а может и больше).

Сейчас код допишу и на SSD протестю. Сможет ли на __самом__ дешевом SSD (покупал пару лет назад за 2 тыс. рублей ))) ) сливать пару сотен файлов одновременно.

Сложность алгоритма в виде логарифма от степени двойки - это конечно хорошо. Но логарифм от сотни/тысячи - выглядит намного лучше ))) IMHO & AFAIK
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39418175
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevDima T.....
А если все входы собрать в один массив, то каждый раз скан всех входов в поисках минимального.
Разница скана в RAM и доступ к диску/ленте - не порядки, а несколько порядков (тысячи, десятки тысяч раз, а может и больше).
DDR4 - 4,5 Гб/сек, SSD - 0,5 Гб/сек всего в 9 раз, даже одного порядка не набирается.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39418177
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevСейчас код допишу и на SSD протестю.
Интересно не скорость SSD померить, а скорость алгоритма, т.е. сколько IO в байтах. Встрой счетчики: сколько байт записано во временные файлы и сколько всего прочитано из всех файлов включая исходный.
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39418378
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

есть серьёзные основания полагать, что производительность HDD очень зависит от порядка доступа к файлу

н-р сливать в один файл последовательно гораздо быстрее , чем в несколько разных файлов
...
Рейтинг: 0 / 0
Тяпничная huge-сортировка
    #39418402
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)Dima T,

есть серьёзные основания полагать, что производительность HDD очень зависит от порядка доступа к файлу
Нет оснований. По середине между прогой и HDD стоит ОС со своим кэшем и боле-мене выравнивает эту проблему.

kealon(Ruslan)н-р сливать в один файл последовательно гораздо быстрее , чем в несколько разных файлов
Мой алгоритм предполагает random-read и последовательный write.

PS Сортировка деревом триплетов пока не взлетела. Перегруз проца. Дерево из 1024 триплетов (10 уровней) сортировало 68 кб несколько минут :(
Код: plaintext
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.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
/*

Сортировка файла построчно слияниями сортированных последовательностей. 

1й проход: Поиск возрастающих участков файла. Построение списка источников.
В случае заполнения списка источников до достижения конца файла слияние 
половины меньших по размеру источников во временный файл и подключение его
как источника. И т.д. до завершения прохода.

2й проход: Слияние в выходной файл.


*/

#define SOURCE_MAX 1024 // Максимальное количество источников, кратно степени 2
#define STRING_MAX 256 // Максимальный размер строки файла

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdint.h>

// Буфер для кэширования одной строки
struct item_t {
	char data[STRING_MAX];

	bool operator < (item_t const &b) const { return memcmp(data, b.data, STRING_MAX) < 0; }

};

// Интерфейс источника последовательности
class source_t {
	item_t* first;		// Первый элемент в последовательности

public:
	source_t() : first(NULL) {}

	virtual ~source_t() {}

	// Первый элемент в очереди, NULL если пусто
	virtual const item_t* front() {
		if(first == NULL) {
			pop();
		}
		return first;
	}

	// Извлечение следующего элемента
	virtual void pop() {
		first = next();
	}

	// Считывание следующего элемента последовательности, NULL если читать нечего
	virtual item_t* next() {
		return NULL;
	}

	// Общая длина последовательности в любых попугаях, используется для сравнения размеров последовательностей
	virtual size_t size() {
		return 0;
	}
};

// Интерфейс приемника
class destination_t {
public:
	virtual ~destination_t() {}

	// Установка источника
	void source_set(source_t* src) {
		assert(src != NULL);
		// Запись всего что есть в источнике
		const item_t* i;
		while(i = src->front()) {
			write(i);
			src->pop();
		}
	}

	// Запись элемента
	virtual void write(const item_t* item) {

	}
};

// Последовательность из файла или куска файла
class file_t : public source_t, public destination_t {
	item_t item;	// Последняя прочитанная запись
	size_t offset;	// Смешение для чтения следующей строки
	size_t end;		// Конец блока
	FILE* f;		// Файл

public:
	file_t() : f(NULL), offset(0), end(0) {}

	~file_t() {
		assert(end == offset); // Прочитан не полностью
	}

	void init(FILE* f) {
		this->f = f;
	}

	// Чтение ---------------------------------------------
	void init_read(size_t offset, size_t end) {
		this->offset = offset;
		this->end = end;
	}

	// Чтение файла целиком
	void init_read() {
		offset = 0;
		fseek(f, 0, SEEK_END);
		end = ftell(f);
	}

	item_t* next() override {
		if (end <= offset) return NULL;
		if (offset != ftell(f)) {
			// Установка указателя для чтения строки
			if (fseek(f, offset, SEEK_SET) != 0) {
				assert(false); // Невозможно установить позицию в файле
			}
		}
		if (fgets(item.data, STRING_MAX, f) < 0) {
			offset = ftell(f);
			return NULL;
		}
		offset = ftell(f);
		return &item;
	}

	size_t size() override {
		if (end <= offset) return 0;
		return end - offset;
	}

	void print() {
		item_t* i;
		while(i = next()) {
			printf(i->data);
		}
	}

	// Запись ----------------------------------------------
	//void end_write(const item_t* item) {
	//	offset = 0;
	//	fseek(0, 0, SEEK_SET);
	//}

	void write(const item_t* item) override {
		fputs(item->data, f);
	}
};

// Слияние двух последовательностей, выдает общую на выходе
class triplet_t : public source_t {
	source_t* src[2] = {0};	// Источники
	size_t idx = {0};		// Индекс меньшего
	size_t num;
public:

	void init(source_t* src1, source_t* src2, size_t num) {
		assert(src1 != NULL);
		src[0] = src1;
		src[1] = src2;
		this->num = num;
	}

	// Первый элемент в очереди, NULL если пусто
	const item_t* front() override {
		assert(src[0] != NULL);
		if (src[1] == NULL || src[1]->front() == NULL) {
			idx = 0;
		} else if (src[0]->front() == NULL) {
			idx = 1;
		} else if(*src[0]->front() < *src[1]->front()) {
			idx = 0;
		} else {
			idx = 1;
		}
		return src[idx]->front();
	}

	// Извлечение следующего
	void pop() override {
		src[idx]->pop();
	}
};

// Слияние массива src в dest деревом триплетов
void triplet_store(source_t** src, size_t src_size, destination_t& dest) {
	triplet_t trp[SOURCE_MAX];
	assert(src_size != 0 || src_size >= SOURCE_MAX);
	// Инициализация первых триплетов на src_size входов
	size_t cnt = 0;
	for(size_t i = 0; i < src_size + src_size % 2; i += 2) {
		if(i < src_size - 1) {
			trp[cnt].init(src[i], src[i + 1], cnt);
		} else {
			trp[cnt].init(src[i], NULL, cnt);
		}
		cnt++;
	}
	// Инициализация остального дерева
	size_t first = 0, last = cnt;
	while(last - first > 1) {
		for (size_t i = first; i < last + (last - first) % 2; i += 2) {
			if (i < last - 1) {
				trp[cnt].init(&trp[i], &trp[i + 1], cnt);
			} else {
				trp[cnt].init(&trp[i], NULL, cnt);
			}
			cnt++;
			assert(cnt < SOURCE_MAX);
		}
		first = last;
		last = cnt;
	}
	// Сохранение
	dest.source_set(&trp[first]);
}

// Слияние
void triplet_sort(const char* file_source, const char* file_dest) {
	FILE* in = fopen(file_source, "rb");
	assert(in != NULL);
	FILE* out = fopen(file_dest, "wb");
	assert(out != NULL);
	file_t dest;
	dest.init(out);
	// Заполнение источников
	file_t fs[SOURCE_MAX];
	source_t* src[SOURCE_MAX] = {0};
	size_t start = 0;
	item_t item[2];
	size_t idx = 1;
	size_t cnt = 0; // Количество последовательностей
	if(fgets(item[0].data, STRING_MAX, in) >= 0) { // Чтение первого элемента
		for(; cnt < SOURCE_MAX; cnt++) {
			size_t end = ftell(in);
			// Вычитывание возрастающей последовательности
			while(fgets(item[idx].data, STRING_MAX, in) >= 0) {
				idx = 1 - idx;
				// Проверка возрастания, idx предыдуший элемент
				if (item[1 - idx] < item[idx]) {
					break;
				}
				end = ftell(in);
			}
			fs[cnt].init(in);
			fs[cnt].init_read(start, end);
			src[cnt] = &fs[cnt];
			start = end;
		}
		printf("cnt = %d\n", (int)cnt);
	}
	// Слияние в конечный файл
	triplet_store(src, cnt, dest);


	for (size_t i = 0; i < SOURCE_MAX; i++) {
		printf("---- %lld -----\n", (int64_t) i);
		fs[i].print();
	}
	fclose(in);
	fclose(out);
}


// Файл для сортировки можно тут взять http://services.fms.gov.ru/info-service.htm?sid=2000 1.2Гб неупорядоченного текста.
int main() {
	triplet_sort("c:/download/list_of_expired_passports.csv", "c:/download/list_of_expired_passports-sort.csv");
#ifdef _DEBUG
	printf("Press any key ...\n");
	getchar();
#endif
	return 0;
}

...
Рейтинг: 0 / 0
25 сообщений из 133, страница 3 из 6
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Тяпничная huge-сортировка
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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