Помогите написать класс

Модератор: Модераторы

Помогите написать класс

Сообщение CRobin » 26.01.2016 12:45:34

Здравствуйте. Есть таблица с тремя полями key1, key2, value. Оба поля key1 и key2 являются не зависимыми друг от друга уникальными ключами. По ключу key1 происходит добавление/считывание/обновление записи, это служебное поле репликации (техноческий ключ), а по ключу key2 происходит только считывание данных, это идентификатор данных в системе (логический ключ). Количество записей в таблице не определено, но может колебаться в диапазоне от нескольких десятков, до нескольких сотен записей, не более того. Задача в том, чтобы обеспечить максимально возможную скорость считывания и записи данных в многопоточном окружении. Одновременно к таблице обращаются десятки потоков, скорость выполнения каждой операции не должна превышать несколько микросекунд. Скорость критически важна. Буду благодарен тому, кто возьмется подсказать как решить эту задачу.
CRobin
постоялец
 
Сообщения: 145
Зарегистрирован: 26.01.2016 12:15:39

Re: Помогите написать класс

Сообщение resident » 27.01.2016 23:16:08

Обращений по 1 и по 2 одинаковое количество?
Удаление не требуется?
Примеры ключей может приведете?

з.ы. А база данных не подходит?
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Помогите написать класс

Сообщение CRobin » 28.01.2016 03:31:46

База данных не обеспечивает требуемой скорости. Удалось отчасти решить задачу через использование указателей, для key2 просто создается дополнительный массив типа key2=>Key1, а сими данные кладутся в массив key1=>Val. Проблема остается в том, что ключи Key1 и Key2 имеют тип Int64 (примеры 1742123456..1742123789), соответственно массивы с такими ключами не помещаются в память. На данный момент вручную объявляю статические массивы с учетом диапазона, в котором могут быть ключи
Код: Выделить всё
elems : array[1742111111..1743111111] of record
. Если ли способ динамически объявить этот массив так чтоб low(elems) был 1742111111 а не 0?
CRobin
постоялец
 
Сообщения: 145
Зарегистрирован: 26.01.2016 12:15:39

Re: Помогите написать класс

Сообщение Mirage » 28.01.2016 04:50:24

Элементарно же.
Храним в массиве запись (key1, key2, value).
Заводим две хеш-таблицы, отображающие key1 и key2 в индекс в массиве с value.
Т.е. Int64 => Integer.
При считывании, просто получаем по ключу индекс и отдаем из массива по индексу.
При добавлении записи, сперва добавляем в массив с value, затем добавляем индекс в хеш-таблицы.
При обновлении записи, если обновляется только value, но не ключи, просто обновляем value в массиве.
Если обновляется также ключ, то удаляем из хеш-таблицы старый и добавляем новый.
С удалением сложнее: например, удаляем ключи из хеш-таблиц и помечаем как-нибудь в массиве, что запись удалена удаленную.
Время от времени проходимся по всей структуре и перестраиваем ее так, чтобы не было дырок. Небольшой размер позволяет.
Все операции атомарны, например, внутри критической секции.

Есть и другие варианты, в зависимости от недостающих деталей:
как распределены ключи, каков характер доступа, т.е. что чаще - считывание, добавлени, удаление

CRobin писал(а):Если ли способ динамически объявить этот массив так чтоб low(elems) был 1742111111 а не 0?


Да пусть будет 0, можно же прибавлять смещение к индексу, раз оно известно.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Помогите написать класс

Сообщение resident » 28.01.2016 10:50:00

CRobin писал(а): На данный момент вручную объявляю статические массивы с учетом диапазона, в котором могут быть ключи

Этот диапазон будет изменятся?

CRobin писал(а):Если ли способ динамически объявить этот массив так чтоб low(elems) был 1742111111 а не 0?

Зачем динамически?

Добавлено спустя 1 минуту 15 секунд:
CRobin писал(а):соответственно массивы с такими ключами не помещаются в память

Какое ограничение памяти на это?

Добавлено спустя 12 минут 10 секунд:
Mirage писал(а):С удалением сложнее

Вроде удалять не нужно.
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Помогите написать класс

Сообщение Pavia » 28.01.2016 12:00:35

Наймите студента. Он вам всё сделаете.
Задача простая. В ваше ТЗ вписывается массив и линейный поиск.
Если всё же размеры изменяются. То тогда двусвязный список.
А если нужен максимум скорости, то деревья.
Всё это уже описано в книгах про структуры данных и алгоритмы.
Аватара пользователя
Pavia
постоялец
 
Сообщения: 290
Зарегистрирован: 07.01.2011 12:46:51

Re: Помогите написать класс

Сообщение resident » 28.01.2016 16:18:18

Pavia
Если уж начал теоретизировать, так рассказывай с самого начала "Человек произошел от обезьяны ... и т.д.". :)
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Помогите написать класс

Сообщение CRobin » 28.01.2016 19:29:30

Mirage писал(а):При добавлении записи, сперва добавляем в массив с value, затем добавляем индекс в хеш-таблицы.

массив с value в считанные минуты сохрет всю память, поскольку самих обновлений по key1 приходит слишком много (ограничение ширина интернет канала и возможности tcp стека)
Mirage писал(а):Да пусть будет 0, можно же прибавлять смещение к индексу, раз оно известно.

как раз на этом решении я и остановился, но сейчас нахожу проблему, поскольку для использования смещения, нужно точно знать минимальное значение key1
resident писал(а):Этот диапазон будет изменятся?

диапазон значений key1 и диапазон значений key2 может изменятся
resident писал(а):Зачем динамически?

Потому что лиапазон значений ключей может изменятся
resident писал(а):Какое ограничение памяти на это?

для хранения даже одного массива array[int64] of string просто посчитайте сколько нужно для этого памяти
Pavia писал(а):Наймите студента. Он вам всё сделаете.

Студент конечно сделает, но строчки задания, где написано, что скорость не должна превышать микросекунды для него скорее всего это будет пустой звук.
Pavia писал(а):Задача простая. В ваше ТЗ вписывается массив и линейный поиск.

Не подходит ни линейный поиск ни деревья, увы.
CRobin
постоялец
 
Сообщения: 145
Зарегистрирован: 26.01.2016 12:15:39

Re: Помогите написать класс

Сообщение Mirage » 28.01.2016 21:23:31

CRobin писал(а):массив с value в считанные минуты сохрет всю память, поскольку самих обновлений по key1 приходит слишком много (ограничение ширина интернет канала и возможности tcp стека)


Массив с value растет только при добавлении элемента. При обновлении в нем просто изменяется значение на новое.
CRobin писал(а):Количество записей в таблице не определено, но может колебаться в диапазоне от нескольких десятков, до нескольких сотен записей, не более того.


Это говорит о том, что добавлений не много.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Помогите написать класс

Сообщение resident » 28.01.2016 21:46:07

CRobin писал(а):массив с value в считанные минуты сохрет всю память, поскольку самих обновлений по key1 приходит слишком много (ограничение ширина интернет канала и возможности tcp стека)

Кхе, а к чему здесь вообще сторонний массив?
Также две хеш таблицы.
В первой по 1-му ключу искать связный список и в нем уже копаться ища нужную запись. Список-массив можно и сортировать при вставке для пущей скорости.
Во второй будет таким же образом хранится зависимость 1-го ключа от 2-го.

CRobin писал(а):для хранения даже одного массива array[int64] of string просто посчитайте сколько нужно для этого памяти

Это понятно, вы сколько можете выделить на решение?

Добавлено спустя 11 минут 32 секунды:
Mirage писал(а):Время от времени проходимся по всей структуре и перестраиваем ее так, чтобы не было дырок.

Дырки от удаленных в массиве?
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Помогите написать класс

Сообщение Mirage » 28.01.2016 22:48:32

resident писал(а):Дырки от удаленных в массиве?


Да. Если удалений нет, то это не нужно и такой вариант самый быстрый.
Если удаления нужны, то лучше действительно только хэшмапы оставить, одна отображает key1 на запись с данными, другая key2 на key1.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Помогите написать класс

Сообщение resident » 28.01.2016 23:32:13

Ok
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Помогите написать класс

Сообщение CRobin » 29.01.2016 14:02:12

Mirage писал(а):Массив с value растет только при добавлении элемента. При обновлении в нем просто изменяется значение на новое.


Прошу прощения, недопонял сразу. Действительно, решение со всех сторон оптимально, остается только каким то образом выяснить минимальные значение key1 b key2 для того чтоб делать offset.
CRobin
постоялец
 
Сообщения: 145
Зарегистрирован: 26.01.2016 12:15:39

Re: Помогите написать класс

Сообщение Mirage » 29.01.2016 14:31:32

CRobin писал(а):для того чтоб делать offset.


key1 и key2 используются как ключи в хеш-мапах. Поэтому им никакой offset не требуется. Требуется приличная хеш функция для int64.
Массив value растет постепенно, индекс очередного элемента кладется в хеш-мапы. Offset также не требуется.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Re: Помогите написать класс

Сообщение CRobin » 30.01.2016 03:11:32

На данный момент воспользовался вашим советом
Mirage писал(а):пусть будет 0, можно же прибавлять смещение к индексу, раз оно известно
и храню данные в двух массивах с ключами key = key - min(key). Запись/чтение до 1мкс на относительно слабой машине меня устраивает, благодарю за решение.
CRobin
постоялец
 
Сообщения: 145
Зарегистрирован: 26.01.2016 12:15:39


Вернуться в Помощь за вознаграждение

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru