Изменения

Перейти к: навигация, поиск

Обсуждение участника:Kurkin

4638 байт добавлено, 20:46, 6 июня 2015
Нет описания правки
=Quotient filter={{Определение|definition ='''Quotient filter''' {{---}} вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное(элемент в множестве есть, но структура данных сообщает, что его нет).}}
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления и удаления элементов нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания.
Структура разработана в 2011 году Бендером как замена [[:Фильтр_Блума|фильтра Блума]].
==Описание структуры данных==
Фильтр представляет собой хеш таблицу , в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В <tex>Quotient filter</tex> хеш функция возвращает <tex>p</tex> битовый хеш, последние r бит которого называются остатокостатком, а <tex>q = p - r</tex> старших бит называются частное частным (англ. ''quotient''), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет <tex>2^q</tex>.
Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно , ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.
Последовательность ячеек , имеющих одинаковые частные называется пробегом (англ. ''run''). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом.
Пробег , у которого первый элемент занимает каноническую ячейку , является началом кластера. Кластер (англ. ''cluster'') {{---}} объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.
Три дополнительных бита имеют следующие функции:
# <tex>is</tex> <tex>occupied</tex> бит занятости {{---}} равно равен единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке. # <tex>is</tex> <tex>continuation</tex> бит продолжения {{---}} равно равен единице, если ячейка занята, но не первым элементов пробеге.# бит сдвига {{---}} равен единице, если пробег сдвинут относительно канонического слота.   Возможные состояния: 0 0 0 : Пустая ячейка. 0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. 0 1 0 : не используется. 0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. 1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. 1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. 1 1 0 : не используется. 1 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.  === Поиск === Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве.Если бит занятости единица, то нам нужно найти пробег для <tex>isDq</tex> . Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>shiftedDq</tex> {{---}} равно и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единицеувеличивает счетчик на <tex>1</tex>. После того как мы нашли начало кластера, если пойдем от него влево, каждая ячейка с битом продолжения равным нулю говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нужный нам пробег сдвинут относительно канонического слотадля <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> ,вероятно, содержится в множестве, иначе <tex>D</tex> точно не содержится в множестве. === Вставка === Аналогично с поиском: найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты.  * Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу.* Если мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.  == Преимущества == * Последовательное расположение данных. Можно загружать только 1 кластер, уменьшая количество кеш промахов.* Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.* Простое слияние двух фильтров. ==См.Также== *[[:Идеальное_хеширование|Идеальное хеширование]]*[[:Универсальное_хеширование|Универсальное хеширование]]  
== Источники ==
41
правка

Навигация