PD>Дан файл в формате CSV. 10 полей на строчку, есть пустые поля. Поля не длинные, обычно 5-10 символов. Количество строк известно, порядка 5 миллионов. Размер файла 200 Мб, известен точно.
PD>Делай что хочешь, но должен обеспечить
PD>2. Выдачу строк, отсортированых по любому из первых трех полей. (SELECT * ORDER BY FIELD1) PD>3. Выдачу любого набора полей в любом порядке из строк, отсортированных по любому из первых трех полей (SELECT FIELD2,FIELD5 ORDER BY FIELD1) PD>4. Выдачу аналогично п.3, но только для тех строк, у которых поле сортировки равно чему-то (SELECT FIELD2,FIELD5 ORDER BY FIELD1 WHERE FIELD1="ABCD")
PD>Для п.2-4 сортировка в момент запроса не допускается. Данные должны быть готовы для выдачи в этот момент без какой бы то ни было модификации.
PD>Вся информация должна быть в ОП, чтение из файла можно провести только один раз. PD>Можешь завести нужные вспомогательные структуры, массивы и т.п, но копировать строки не разрешается. Иными словами, каждая исходное текстовое поле должно присутствовать в памяти ТОЛЬКО ОДИН РАЗ. Хоть явно, хоть неявно. На вспомогательные структуры, так и быть, еще 50-70 Мб дам.
Заводим буфер длиной на 1 байт больше чем размер файла. Читаем файл в буфер целиком в двоичном виде.
Заводим три массива указателей p1,p2,p3 размером в количество строк (оно известно)
Проходим по буферу, заменяем запятые на нули. В конце строки нет запятой, но есть CR/LF. CR заменяем на 0, LF игнорируем.
(Осторожно! В самом конце файла может CR/LF не быть. Именно поэтому я задал буфер на 1 байт больше. Если это так, записываем 0 в конце)
По ходу этого прохода формируем массив p1 как массив указателей на начала строк как они были (и есть)
Копируем p1 в p2 и p3
Сортируем p1 , используя в качестве ключа первое текстовое поле. Там asciiz, так что используем стандартные qsort и strcmp
Сортируем p2 по второму, и p3 по третьему полю таким же образом. Поскольку у нас строки заканчиваются нулем, переход от одного поля к другому не вызывает проблем. Фактически мы здесь имеем почти multi-sz формат, только без завершающего нуля.
PD>1. Выдачу этих строк в исходном порядке
Пройти буфер подряд без использования этих указателей
PD>2. Выдачу строк, отсортированых по любому из первых трех полей. (SELECT * ORDER BY FIELD1)
Пройти буфер в порядке p1, p2 или p3
PD>3. Выдачу любого набора полей в любом порядке из строк, отсортированных по любому из первых трех полей (SELECT FIELD2,FIELD5 ORDER BY FIELD1)
Аналогично 2, но выбирать только нужные поля.
PD>4. Выдачу аналогично п.3, но только для тех строк, у которых поле сортировки равно чему-то (SELECT FIELD2,FIELD5 ORDER BY FIELD1 WHERE FIELD1="ABCD")
Провести двоичный поиск в массиве p1, p2 или p3 соответственно, найти начало и конец участка, соответствующего требуемому полю сортировки, далее аналогично 3.
Задача решается для любого размера как исходных строк, так и полей.