Автор оригинала: David Wong.
Продолжайте с нашими объектами и типами данных.
В предыдущем разделе мы узнали о строках и списках, за которыми следуют хэши, коллекции и упорядоченные коллекции.
1 Хэш-объект
Необязательными кодами для объектов Hashi являются ziplist и hashtable соответственно.
1.1 Объект Hashi, закодированный ziplist
Объект Hashi, закодированный в ziplist, сжимается с использованием списка в качестве базовой реализации. Всякий раз, когда к хэш-объекту добавляется новая пара ключ-значение, программа сначала сохраняет ее. ключ Сжатые узлы списка перемещаются в конец таблицы, а затем сохраняются значение Узел сжатого списка перемещается в конец таблицы. Так:
- Два узла, сохраняющие пару ключ-значение, всегда находятся близко друг к другу. Узел, сохраняющий ключ, находится спереди, а узел, сохраняющий значение, – сзади.
- Пара ключ-значение, добавленная в хэш-объект, сначала копируется как направление заголовка сжатого списка, а затем добавленная пара ключ-значение помещается в хвостовом направлении сжатого списка.
Выполните следующую команду SET, и сервер создаст объект списка в качестве значения ключа профиля, как показано на рисунке 9:
127.0.0.1:6379> HSET profile name "Tom" (integer) 1 127.0.0.1:6379> HSET profile age "25" (integer) 1 127.0.0.1:6379> HSET profile career "Programer" (integer) 1 127.0.0.1:6379> OBJECT ENCODING profile "ziplist"
Сжатый список, используемый объектом, показан на рисунке 10.
1.2 Закодированная хэш-таблица
Объект Hashi, закодированный в хэш-таблице, реализован со словарем в качестве нижнего слоя. Каждая пара ключ-значение в хэш-объекте сохраняется с помощью пары ключ-значение словаря:
- Каждый ключ в словаре представляет собой строковый объект, в котором хранятся ключи пар ключ-значение.
- Каждое значение в словаре представляет собой строковый объект, в котором хранится значение пары ключ-значение.
Если предыдущий ключ профиля использует хэш-объект, закодированный в хэш-таблице, то хэш-объект должен быть показан на рисунке 11.
1.3 преобразование кода
Когда объект Hashi соответствует следующим двум условиям, будет использоваться код ziplist:
- Для всех пар ключ-значение, сохраненных хэш-объектами, длина строки ключей и значений составляет менее 64 байт.
- Количество пар ключей, сохраненных хэш – объектами, составляет менее 512.
Критические значения в приведенных выше условиях соответствуют конфигурациям в файле redis .conf: хэш-максимальное значение-ziplist-значение и хэш-макс-ziplist-записи 。
В версии 3.2 при добавлении значения хэш-ключа всегда создается хэш-объект, закодированный в ziplist, а затем выполняется проверка преобразования. Существует две ситуации, когда происходит преобразование кодирования:
- При обновлении или добавлении пар значений ключей, если Количество байтов значений больше
hash-max-ziplist-значениеОн изменится с кодировки ziplist на кодировку хэш-таблицы. - При добавлении новых пар ключ-значение, если логарифм значения ключа больше, чем
hash-max-ziplist-записиОн будет преобразован из кодировки ziplist в кодировку хэш-таблицы.
Следует отметить, что ни одно из вышеперечисленных преобразований не произойдет из хэш-таблицы в ziplist, даже если они соответствуют требованиям.
Для функций преобразования кодировки хэша вы можете обратиться к t_hash.c/преобразование типа хэша, которое выглядит следующим образом:
O is the original object, and enc is the target encoding.
void hashTypeConvert(robj *o, int enc) {
If (o->encoding = = OBJ_ENCODING_ZIPLIST) {// the original code is OBJ_ENCODING_ZIPLIST.
hashTypeConvertZiplist(o, enc);
} else if (o->encoding == OBJ_ENCODING_HT) {
serverPanic("Not implemented");
} else {
serverPanic("Unknown hash encoding");
}
}2 Объекта Коллекции
Необязательная кодировка объекта коллекции-intset и хэш-таблица.
2.1 объекты кодированной коллекции intset
Объекты коллекции с кодировкой интенсивности используют целочисленные наборы в качестве базовых реализаций, и все элементы, содержащиеся в объекте коллекции, хранятся в целочисленном наборе.
Чтобы выполнить следующую команду SADD, мы создадим объект коллекции с кодировкой intset, показанный на рисунке 12:
127.0.0.1:6379> SADD numbers 1 3 5 (integer) 3 127.0.0.1:6379> OBJECT ENCODING numbers "intset"
2.2 объекты кодированной коллекции с хэш-таблицей
Объект коллекции, закодированный в хэш-таблице, реализован со словарем в качестве нижнего слоя. Каждый ключ в словаре является строковым объектом, и каждый строковый объект содержит элемент коллекции, в то время как значение словаря имеет значение NULL.
Чтобы выполнить следующую команду SADD, мы создадим объект кодированной коллекции с хэш-таблицей, показанный на рисунке 13:
127.0.0.1:6379> SADD fruits "apple" "banana" "cherry" (integer) 3 127.0.0.1:6379> OBJECT ENCODING fruits "hashtable"
2.3 преобразование кода
Когда объект набора удовлетворяет одновременно двум следующим условиям, объект использует кодировку intset:
- Все элементы, сохраненные объектом коллекции, могут быть представлены в виде целых значений с помощью длинного двойника.
- Объекты коллекции содержат не более 512 элементов.
Критические значения в приведенных выше условиях соответствуют конфигурациям в файле redis.conf: set-max-intset-записи 。
Для объекта коллекции при добавлении первой пары ключ-значение проверяется значение пары ключ-значение. Если задано целочисленное значение, создается объект коллекции с кодировкой intset. В противном случае создается объект коллекции, закодированный в хэш-таблице.
Существует две ситуации, когда происходит преобразование кодирования:
- При обновлении или добавлении пар значений ключей, если значение
- Он не может быть представлен длинным двойным и будет преобразован из кодировки intset в кодировку хэш-таблицы. При добавлении новой пары ключ-значение, если пара ключ-значение находится в наборе Значение ключа логарифмическое число
большеset-max-intset-записи
Аналогично, преобразование из хэш-таблицы в набор intset не выполняется, даже если оно соответствует критериям.
Для функций преобразования хэш-кодирования вы можете обратиться к преобразованию типа t_set.c/set. Исходный код выглядит следующим образом:
Setobj is the original object, and enc is the target encoding.
hvoid setTypeConvert(robj *setobj, int enc) {
setTypeIterator *si;
serverAssertWithInfo(NULL,setobj,setobj->type == OBJ_SET && setobj->encoding == OBJ_ENCODING_INTSET);
If (enc == OBJ_ENCODING_HT) {// can only be converted to OBJ_ENCODING_HT encoding
int64_t intele;
dict *d = dictCreate(&setDictType,NULL);
robj *element;
/* Presize the dict to avoid rehashing */
dictExpand(d,intsetLen(setobj->ptr));
/* To add the elements we extract integers and create redis objects */
si = setTypeInitIterator(setobj);
while (setTypeNext(si,&element,&intele) != -1) {
element = createStringObjectFromLongLong(intele);
serverAssertWithInfo(NULL,element,
dictAdd(d,element,NULL) == DICT_OK);
}
setTypeReleaseIterator(si);
setobj->encoding = OBJ_ENCODING_HT;
zfree(setobj->ptr);
setobj->ptr = d;
} else {
serverPanic("Unsupported set conversion");
}
}3 Упорядоченных Набора Объектов
Необязательная кодировка объектов упорядоченного набора-это список ziplist и список пропусков.
3.1 объекты упорядоченного набора, закодированные в ziplist
Объекты коллекции в кодировке Intset используют сжатый список в качестве базовой реализации. Каждый элемент коллекции сохраняется с помощью двух компактных узлов списка, расположенных рядом друг с другом. Первый узел содержит элемент элемента, а второй элемент содержит оценку элемента.
Элементы набора в сжатом списке отсортированы по баллам от малого до большого. Элементы с меньшими баллами размещаются в направлении заголовка, в то время как элементы с большими баллами размещаются в направлении ближе к концу таблицы.
Чтобы выполнить следующую команду SADD, мы создадим объект коллекции с кодировкой ziplist, показанный на рисунке 14:
127.0.0.1:6379> ZADD price 8.5 apple 5.0 banana 6.0 cherry (integer) 3 127.0.0.1:6379> OBJECT ENCODING price "ziplist"
Базовая структура ziplist показана на рисунке 15.
3.2 объекты кодированной коллекции скиплиста
Объекты коллекции, закодированные в скиплистах, реализуются с использованием набора в качестве базовой реализации. Структура набора содержит как словарь, так и таблицу переходов. Структура исходного кода выглядит следующим образом:
# server.h
typedef struct zset {
dict *dict;
zskiplist *zsl;
} zset;Таблица переходов ZSL в структуре Zset сохраняет все элементы набора от малого до большого по баллам, и каждый узел таблицы переходов сохраняет элемент набора.
Атрибут объекта узла таблицы переходов сохраняет элементы элемента, в то время как атрибут оценки узла таблицы переходов сохраняет ветви элемента. * * Программа использует эту таблицу переходов для выполнения операций с диапазонами для упорядоченных наборов. Например, такие команды, как ZRANK и ZRANGE, реализованы на основе API таблицы переходов.
Кроме того, словарь dict в структуре Zset создает сопоставление элементов с оценками для упорядоченных наборов. Каждая пара ключ-значение в словаре содержит элемент набора: ключ в словаре содержит элементы элемента, в то время как значение в словаре содержит оценку элемента. С помощью этого словаря программа использует сложность O (1), чтобы найти оценку данного участника.
Члены каждого элемента в упорядоченном наборе являются строковым объектом, а оценка каждого элемента представляет собой число с плавающей запятой двойного типа. Это стоит упомянуть что, хотя структура Zset использует как таблицы переходов, так и словари для хранения элементов упорядоченных наборов, обе структуры данных совместно используют элементы и значения одних и тех же элементов через указатели, поэтому повторяющиеся элементы и значения не генерируются и дополнительная память не тратится впустую.
Если предыдущий ключ цены создан вместо объекта упорядоченной коллекции с кодировкой ziplist вместо кодировки skiplist, то объект упорядоченной коллекции будет показан на рисунке 16, а результат Zset, используемый объектом, будет показан на рисунке 17.
На рисунке 17 элементы и оценки каждого элемента показаны несколько раз для удобства представления. Фактически, они являются членами и ценностями общих элементов.
3.3 Преобразование Кодирования
Когда упорядоченные агрегированные объекты одновременно удовлетворяют следующим двум условиям, объект кодируется с помощью ziplist:
- Упорядоченные объекты коллекции содержат не более 128 элементов.
- Длина всех элементов, хранящихся в упорядоченном наборе, составляет менее 64 байт.
Критические значения в приведенных выше условиях соответствуют конфигурациям в файле redis.conf: zset-max-ziplist-записи и zset-max-ziplist-значение 。
Для объекта коллекции при добавлении нового значения ключа проверяются значения элементов коллекции и пар значений ключей. Если условия выполнены, создается объект коллекции с кодировкой ziplist, в противном случае создается объект коллекции с кодировкой skiplist. Соответствующий исходный код выглядит следующим образом:
# t_zset.c/zaddGenericCommand
...
zobj = lookupKeyWrite(c->db,key);
if (zobj == NULL) {
if (xx) goto reply_to_client; /* No key + XX option: nothing to do. */
if (server.zset_max_ziplist_entries == 0 ||
server.zset_max_ziplist_value < sdslen(c->argv[scoreidx+1]->ptr))
{
# The number of object elements is 0, or
zobj = createZsetObject();
} else {
zobj = createZsetZiplistObject();
}
dbAdd(c->db,key,zobj);
} else {
if (zobj->type != OBJ_ZSET) {
addReply(c,shared.wrongtypeerr);
goto cleanup;
}
}резюме
- Хэш-объектами являются ziplist и хэш-таблица
- Код. Объекты коллекции имеют вставку и хэш-таблица
- Код. Упорядоченные объекты набора имеют ziplist и шкипер
Оригинал: “https://developpaper.com/read-the-source-code-with-dabin-redis-6-objects-and-data-types-2/”