41
правка
Изменения
Нет описания правки
Фильтр представляет собой [[:Хеш-таблица|хеш-таблицу]], в которой харанится часть ключа и <tex>3</tex> бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш-таблице. В quotient filter хеш-функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются '''остатком''' (англ. ''remainder''), а <tex>q = p - r</tex> старших бит называются '''частным''' (англ. ''quotient''), отсюда название структуры Quotient filter<ref>Knuth, Donald (1973). The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13: Addison Wesley</ref>. Размер хеш-таблицы составляет <tex>2^q</tex>.
Пусть у нас есть ключ <tex>K</tex>, его хеш обозначим <tex>h(K)</tex>, остаток <tex>h_r</tex> и частное <tex>h_q</tex>. Попробуем поместить остаток в хеш-таблицу в ячейку с индексом <tex>h_q</tex>, называемую канонической. Возможно, ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. Этот способ решения колизий схож с [[:Разрешение_коллизий|линейным методом разрешения колизий]].
Последовательность ячеек, имеющих одинаковые частные называется '''пробегом''' (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом.
Пробег, у которого первый элемент занимает каноническую ячейку, является началом кластера. '''Кластер''' {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.
Три дополнительных бита имеют следующие функции:
=== Поиск ===
Пусть мы ищем ключ <tex>K</tex>. Смотрим в его каноническую ячейку с индексом <tex>h_q</tex>, это каноническая ячейка для частного <tex>h_q</tex>. Если в этой ячейке бит занятости не единица, то элемент точно не содержится в множестве.Если бит занятости единица, то нам нужно найти пробег для <tex>h_q</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки с индексом <tex>h_q</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от ячейки с индексом <tex>h_q</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег для частного <tex>h_q</tex>. Если в этом пробеге содержится <tex>h_r</tex>, то <tex>K</tex>, вероятно, содержится в множестве, иначе <tex>K</tex> точно не содержится в множестве.
=== Вставка ===