Обсуждение участника:Kurkin — различия между версиями
Kurkin (обсуждение | вклад) |
Kurkin (обсуждение | вклад) |
||
Строка 10: | Строка 10: | ||
==Описание структуры данных== | ==Описание структуры данных== | ||
− | Фильтр представляет собой хеш таблицу в которой харанится часть ключа и 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). Размер хеш таблицы составляет 2^q. | + | Фильтр представляет собой хеш таблицу в которой харанится часть ключа и 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>, называемую канонической. Возможно ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. | Пусть у нас есть ключ <tex>D</tex>, его хеш обозначим <tex>Dh</tex>, остаток <tex>Dr</tex> и частное <tex>Dq</tex>. Попробуем поместить остаток в хеш таблицу в ячейку <tex>Dq</tex>, называемую канонической. Возможно ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа. | ||
Строка 23: | Строка 23: | ||
# бит сдвига {{---}} равно единице, если пробег сдвинут относительно канонического слота. | # бит сдвига {{---}} равно единице, если пробег сдвинут относительно канонического слота. | ||
− | + | ||
− | + | Возможные состояния: | |
− | + | 0 0 0 : Пустая ячейка. | |
− | 0 0 0 : Пустая ячейка. | + | 0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. |
− | 0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. | + | 0 1 0 : не используется. |
− | 0 1 0 : не используется. | + | 0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. |
− | 0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. | + | 1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. |
− | 1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. | + | 1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. |
− | 1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. | + | 1 1 0 : не используется. |
− | + | 1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. | |
− | 1 1 0 : не используется. | ||
− | 1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. | ||
− | |||
=== Поиск === | === Поиск === | ||
− | Пусть мы ищем ключ D. Смотрим в его каноническую ячейку Dq. Если бит занятости не единица, то элемент точно не содержится в множестве. | + | Пусть мы ищем ключ <tex>D</tex>. Смотрим в его каноническую ячейку <tex>Dq</tex>. Если бит занятости не единица, то элемент точно не содержится в множестве. |
− | Если бит занятости единица, то нам нужно найти пробег для Dq. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки Dq и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от Dq будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на 1. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю, говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нажный нам пробег для Dq. Если в этом пробеге содержится Dr, то D вероятно содержится в множестве, иначе D точно не содержится в множестве. | + | Если бит занятости единица, то нам нужно найти пробег для <tex>Dq</tex>. Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки <tex>Dq</tex> и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от <tex>Dq</tex> будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на 1. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю, говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нажный нам пробег для <tex>Dq</tex>. Если в этом пробеге содержится <tex>Dr</tex>, то <tex>D</tex> вероятно содержится в множестве, иначе <tex>D</</tex> точно не содержится в множестве. |
=== Вставка === | === Вставка === | ||
− | Анологично с поиском найдем найдем позицию для Dr, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. | + | Анологично с поиском найдем найдем позицию для <tex>Dr</tex>, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты. |
− | * Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке Dq в единицу. | + | * Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке <tex>Dq</tex> в единицу. |
− | * Усли мы вставляем Dr в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения. | + | * Усли мы вставляем <tex>Dr</tex> в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения. |
* Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули. | * Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули. | ||
Версия 20:21, 6 июня 2015
Содержание
Quotient filter
Определение: |
Quotient filter — вероятностная структура данных, позволяющая проверить принадлежность элемента множеству. При этом существует возможность получить ложноположительное срабатывание (элемента в множестве нет, но структура данных сообщает, что он есть), но не ложноотрицательное. |
Существует связь между размером хранилища и шансом ложноположительного срабатывания. Поддерживаются операции добавления нового элемента в множество. С увеличением размера хранимого множества повышается вероятность ложного срабатывания.
Структура разработана в 2011 году Бендером как замена фильтра Блума.
Описание структуры данных
Фильтр представляет собой хеш таблицу в которой харанится часть ключа и 3 бита дополнительной информации. Они используются для разрешения ситуации, когда хеш различных ключей указывает на одну ячейку в хеш таблице. В
хеш функция возвращает битовый хеш, последние r бит которого называются остаток, а старших бит называются частное (англ. quotient), отсюда название структуры Quotient filter(придумано Кнутом в The Art of Computer Programming:Searching and Sorting, volume 3. Section 6.4, exercise 13). Размер хеш таблицы составляет .Пусть у нас есть ключ
, его хеш обозначим , остаток и частное . Попробуем поместить остаток в хеш таблицу в ячейку , называемую канонической. Возможно ячейка уже занята, так как существует шанс полных коллизий (остаток и частное разных ключей совпадают) или частичных коллизий (частное разных ключей совпадают). Когда каноническая ячейка занята, помещаем остаток в какую-то ячейку справа.Последовательность ячеек имеющих одинаковые частные называется пробегом (англ. run). Возможно, что начало пробега не занимает канонический слот, если он уже занят каким-то другим пробегом.
Пробег у которого первый элемент занимает каноническую ячейку является началом кластера. Кластер (англ. cluster) — объединение последовательных пробегов, концом кластера является пустая ячейка или начало другого кластера.
Три дополнительных бита имеют следующие функции:
- бит занятости — равно единице, если ячейка является канонической для некого ключа в фильтре, сохраненого необязательно в этой ячейке.
- бит продолжения — равно единице, если ячейка занята, но не первым элементов пробеге.
- бит сдвига — равно единице, если пробег сдвинут относительно канонического слота.
Возможные состояния: 0 0 0 : Пустая ячейка. 0 0 1 : Ячейка содержит начало пробега, сдвинутого относительно канонического слота. 0 1 0 : не используется. 0 1 1 : Ячейка содержит элемент пробега(не первый), сдвинутого относительно канонического слота. 1 0 0 : Ячейка содержит первый элемет пробега в его каноническом слоте. 1 0 1 : Ячейка содержит первый элемет пробега, сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо. 1 1 0 : не используется. 1 1 1 : Ячейка содержит элем ент пробега(не первый), сдвинутого относительно канонического слота. Ячейка является канонической, для существующего пробега сдвинутого вправо.
Поиск
Пусть мы ищем ключ
. Смотрим в его каноническую ячейку . Если бит занятости не единица, то элемент точно не содержится в множестве. Если бит занятости единица, то нам нужно найти пробег для . Так как начало нужного пробега может быть сдвинуто, найдем начало кластера. Идем влево от ячейки и ищем первую с битом сдвига равным нулю, эта ячейка и будет началом кластера. Пока мы идем влево от будем поддерживать счетчик, который бедет показывать сколько пробегов нам нужно будет пропустить от начала кластера. Каждая ячейка с битом занятости равным единице увеличивает счетчик на 1. После того как мы нашли начало кластера, пойдем от него в лево, каждая ячейка с битом продолжения равным нулю, говорит о завершении пробега, когда счетчик станет равным нулю мы найдем нажный нам пробег для . Если в этом пробеге содержится , то вероятно содержится в множестве, иначе точно не содержится в множестве.Вставка
Анологично с поиском найдем найдем позицию для
, сдвигаем на одну позицию влево все эллементы кластера, начиная с выбранного, обновляем дополнительные биты.- Сдвиг не влияет на бит занятости. Выставляем бит занятости в ячейке в единицу.
- Усли мы вставляем в начало пробега, следовательно предыдущий элемент пробега стал вторым, у него нужно выставить бит продолжения.
- Мы выставляем бит сдвига в единицу для каждой ячейки, что мы сдвинули.
Преимущества
- Последовательное расположение данных. Можно загружать только 1 кластер, умменьшая количество кеш промахов.
- Простое увеличение или уменьшение хеш таблицы, достаточно перенести один бит из остатка в частное или наоборот.
- Простое слияние двух фильтров.