diff --git a/Knot.files b/Knot.files
index e82d265ea19e947eae31a115c567fa6d3f9d9935..91431d1fe585c5bb89884c47a81bc812bc35e60f 100644
--- a/Knot.files
+++ b/Knot.files
@@ -30,7 +30,6 @@ src/contrib/fnv/hash_64a.c
 src/contrib/fnv/longlong.h
 src/contrib/getline.c
 src/contrib/getline.h
-src/contrib/hat-trie/hat-trie.h
 src/contrib/hhash.c
 src/contrib/hhash.h
 src/contrib/lmdb/lmdb.h
@@ -50,8 +49,8 @@ src/contrib/openbsd/strlcpy.c
 src/contrib/openbsd/strlcpy.h
 src/contrib/print.c
 src/contrib/print.h
-src/contrib/qp-trie/qp.c
-src/contrib/qp-trie/qp.h
+src/contrib/qp-trie/trie.c
+src/contrib/qp-trie/trie.h
 src/contrib/sockaddr.c
 src/contrib/sockaddr.h
 src/contrib/string.c
diff --git a/src/Makefile.am b/src/Makefile.am
index a62a54b9d382bf8c1c41fed5bbd08dda06da51c1..d2a437d4318368a3d1535576643fb9ba4611d07e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -49,7 +49,6 @@ libcontrib_la_SOURCES = 			\
 	contrib/fnv/longlong.h			\
 	contrib/getline.c			\
 	contrib/getline.h			\
-	contrib/hat-trie/hat-trie.h		\
 	contrib/hhash.c				\
 	contrib/hhash.h				\
 	contrib/macros.h			\
@@ -59,8 +58,8 @@ libcontrib_la_SOURCES = 			\
 	contrib/net.h				\
 	contrib/print.c				\
 	contrib/print.h				\
-	contrib/qp-trie/qp.c			\
-	contrib/qp-trie/qp.h			\
+	contrib/qp-trie/trie.c			\
+	contrib/qp-trie/trie.h			\
 	contrib/sockaddr.c			\
 	contrib/sockaddr.h			\
 	contrib/string.c			\
diff --git a/src/contrib/hat-trie/hat-trie.h b/src/contrib/hat-trie/hat-trie.h
deleted file mode 100644
index 1e57fc2c7f6907f4dcffc3a8505e07bf14a18669..0000000000000000000000000000000000000000
--- a/src/contrib/hat-trie/hat-trie.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*  Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include "contrib/qp-trie/qp.h"
-#include "contrib/hhash.h"
-
-typedef trie_t hattrie_t;
-typedef trie_it_t hattrie_iter_t;
-
-inline static hattrie_t* hattrie_create(struct knot_mm *mm)
-{
-	return trie_create(mm);
-}
-
-inline static void hattrie_free(hattrie_t *trie)
-{
-	trie_free(trie);
-}
-
-inline static void hattrie_clear(hattrie_t *trie)
-{
-	trie_clear(trie);
-}
-
-inline static size_t hattrie_weight(const hattrie_t *trie)
-{
-	return trie_weight(trie);
-}
-
-inline static int hattrie_apply_rev(hattrie_t *trie, int (*f)(value_t*,void*), void* d)
-{
-	return trie_apply(trie, f, d);
-}
-
-inline static value_t* hattrie_tryget(hattrie_t *trie, const char *key, size_t len)
-{
-	return trie_get_try(trie, key, len);
-}
-
-inline static value_t* hattrie_get(hattrie_t *trie, const char *key, size_t len)
-{
-	return trie_get_ins(trie, key, len);
-}
-
-inline static int hattrie_find_leq(hattrie_t *trie, const char *key, size_t len, value_t **dst)
-{
-	return trie_get_leq(trie, key, len, dst);
-}
-
-inline static int hattrie_del(hattrie_t *trie, const char* key, size_t len, value_t *val)
-{
-	return trie_del(trie, key, len, val);
-}
-
-inline static hattrie_iter_t* hattrie_iter_begin(hattrie_t *trie)
-{
-	return trie_it_begin(trie);
-}
-
-inline static void hattrie_iter_next(hattrie_iter_t *it)
-{
-	trie_it_next(it);
-}
-
-inline static bool hattrie_iter_finished(hattrie_iter_t *it)
-{
-	return trie_it_finished(it);
-}
-
-inline static void hattrie_iter_free(hattrie_iter_t *it)
-{
-	trie_it_free(it);
-}
-
-inline static const char* hattrie_iter_key(hattrie_iter_t *it, size_t *len)
-{
-	return trie_it_key(it, len);
-}
-
-inline static value_t* hattrie_iter_val(hattrie_iter_t *it)
-{
-	return trie_it_val(it);
-}
diff --git a/src/contrib/qp-trie/qp.c b/src/contrib/qp-trie/trie.c
similarity index 99%
rename from src/contrib/qp-trie/qp.c
rename to src/contrib/qp-trie/trie.c
index 6f9b9dbb32812f136b066e76da51bbd28c53bbcb..bb24f572b1def1567903c1ba219c5cd741559317 100644
--- a/src/contrib/qp-trie/qp.c
+++ b/src/contrib/qp-trie/trie.c
@@ -21,7 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "contrib/qp-trie/qp.h"
+#include "contrib/qp-trie/trie.h"
 #include "contrib/macros.h"
 #include "contrib/mempattern.h"
 #include "libknot/errcode.h"
diff --git a/src/contrib/qp-trie/qp.h b/src/contrib/qp-trie/trie.h
similarity index 100%
rename from src/contrib/qp-trie/qp.h
rename to src/contrib/qp-trie/trie.h
diff --git a/src/knot/conf/base.c b/src/knot/conf/base.c
index c595668abe296cce49cb462689fa3cdc69c92bf0..78bd7a6e14ef333512c13105aaea3f5a7e7dd51e 100644
--- a/src/knot/conf/base.c
+++ b/src/knot/conf/base.c
@@ -360,7 +360,7 @@ void conf_free(
 		conf->api->txn_abort(conf->io.txn_stack);
 	}
 	if (conf->io.zones != NULL) {
-		hattrie_free(conf->io.zones);
+		trie_free(conf->io.zones);
 		mm_free(conf->mm, conf->io.zones);
 	}
 
diff --git a/src/knot/conf/base.h b/src/knot/conf/base.h
index 4cd69f8570f8e81c2873c166ec49ab88c6a4d1b0..436d9d9180045a6063db1501c73d42262c567edf 100644
--- a/src/knot/conf/base.h
+++ b/src/knot/conf/base.h
@@ -27,7 +27,7 @@
 
 #include "libknot/libknot.h"
 #include "libknot/yparser/ypscheme.h"
-#include "contrib/hat-trie/hat-trie.h"
+#include "contrib/qp-trie/trie.h"
 #include "contrib/ucw/lists.h"
 
 /*! Default template identifier. */
@@ -91,7 +91,7 @@ typedef struct {
 		/*! Master transaction flags. */
 		yp_flag_t flags;
 		/*! Changed zones. */
-		hattrie_t *zones;
+		trie_t *zones;
 	} io;
 
 	/*! Current config file (for reload if started with config file). */
diff --git a/src/knot/conf/confio.c b/src/knot/conf/confio.c
index 422d10ea87aadc4202d9b1a8266951103e22fbbb..da54afb54d091f9450cc8c6d12405e92ca108a65 100644
--- a/src/knot/conf/confio.c
+++ b/src/knot/conf/confio.c
@@ -83,7 +83,7 @@ int conf_io_begin(
 	if (!child) {
 		conf()->io.flags = CONF_IO_FACTIVE;
 		if (conf()->io.zones != NULL) {
-			hattrie_clear(conf()->io.zones);
+			trie_clear(conf()->io.zones);
 		}
 	}
 
@@ -130,7 +130,7 @@ void conf_io_abort(
 	if (!child) {
 		conf()->io.flags = YP_FNONE;
 		if (conf()->io.zones != NULL) {
-			hattrie_clear(conf()->io.zones);
+			trie_clear(conf()->io.zones);
 		}
 	}
 }
@@ -442,18 +442,18 @@ static int diff_zone_section(
 		return KNOT_EOK;
 	}
 
-	hattrie_iter_t *it = hattrie_iter_begin(conf()->io.zones);
-	for (; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
-		io->id = (const uint8_t *)hattrie_iter_key(it, &io->id_len);
+	trie_it_t *it = trie_it_begin(conf()->io.zones);
+	for (; !trie_it_finished(it); trie_it_next(it)) {
+		io->id = (const uint8_t *)trie_it_key(it, &io->id_len);
 
 		// Get the difference for specific zone.
 		int ret = diff_section(io);
 		if (ret != KNOT_EOK) {
-			hattrie_iter_free(it);
+			trie_it_free(it);
 			return ret;
 		}
 	}
-	hattrie_iter_free(it);
+	trie_it_free(it);
 
 	return KNOT_EOK;
 }
@@ -818,9 +818,9 @@ static void upd_changes(
 	}
 
 	// Prepare zone changes storage if it doesn't exist.
-	hattrie_t *zones = conf()->io.zones;
+	trie_t *zones = conf()->io.zones;
 	if (zones == NULL) {
-		zones = hattrie_create(conf()->mm);
+		zones = trie_create(conf()->mm);
 		if (zones == NULL) {
 			return;
 		}
@@ -828,7 +828,7 @@ static void upd_changes(
 	}
 
 	// Get zone status or create new.
-	value_t *val = hattrie_get(zones, (const char *)io->id, io->id_len);
+	trie_val_t *val = trie_get_ins(zones, (const char *)io->id, io->id_len);
 	conf_io_type_t *current = (conf_io_type_t *)val;
 
 	switch (type) {
@@ -846,7 +846,7 @@ static void upd_changes(
 	case CONF_IO_TUNSET:
 		if (*current & CONF_IO_TSET) {
 			// Remove inserted zone -> no change.
-			hattrie_del(zones, (const char *)io->id, io->id_len, NULL);
+			trie_del(zones, (const char *)io->id, io->id_len, NULL);
 		} else {
 			// Remove existing zone.
 			*current |= type;
@@ -1399,12 +1399,12 @@ static int check_zone_section(
 		return KNOT_EOK;
 	}
 
-	hattrie_iter_t *it = hattrie_iter_begin(conf()->io.zones);
-	for (; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
+	trie_it_t *it = trie_it_begin(conf()->io.zones);
+	for (; !trie_it_finished(it); trie_it_next(it)) {
 		size_t id_len;
-		const uint8_t *id = (const uint8_t *)hattrie_iter_key(it, &id_len);
+		const uint8_t *id = (const uint8_t *)trie_it_key(it, &id_len);
 
-		conf_io_type_t type = (conf_io_type_t)(*hattrie_iter_val(it));
+		conf_io_type_t type = (conf_io_type_t)(*trie_it_val(it));
 		if (type == CONF_IO_TUNSET) {
 			// Nothing to check.
 			continue;
@@ -1413,11 +1413,11 @@ static int check_zone_section(
 		// Check specific zone.
 		int ret = check_section(item, id, id_len, io);
 		if (ret != KNOT_EOK) {
-			hattrie_iter_free(it);
+			trie_it_free(it);
 			return ret;
 		}
 	}
-	hattrie_iter_free(it);
+	trie_it_free(it);
 
 	return KNOT_EOK;
 }
diff --git a/src/knot/dnssec/nsec-chain.c b/src/knot/dnssec/nsec-chain.c
index 18a8390c00975ada8fa81cb39b1b88a255dce43c..1f533c261abfa49ab205d5d5622e2099066cd149 100644
--- a/src/knot/dnssec/nsec-chain.c
+++ b/src/knot/dnssec/nsec-chain.c
@@ -162,25 +162,25 @@ int knot_nsec_chain_iterate_create(zone_tree_t *nodes,
 	assert(nodes);
 	assert(callback);
 
-	hattrie_iter_t *it = hattrie_iter_begin(nodes);
+	trie_it_t *it = trie_it_begin(nodes);
 	if (!it) {
 		return KNOT_ENOMEM;
 	}
 
-	if (hattrie_iter_finished(it)) {
-		hattrie_iter_free(it);
+	if (trie_it_finished(it)) {
+		trie_it_free(it);
 		return KNOT_EINVAL;
 	}
 
-	zone_node_t *first = (zone_node_t *)*hattrie_iter_val(it);
+	zone_node_t *first = (zone_node_t *)*trie_it_val(it);
 	zone_node_t *previous = first;
 	zone_node_t *current = first;
 
-	hattrie_iter_next(it);
+	trie_it_next(it);
 
 	int result = KNOT_EOK;
-	while (!hattrie_iter_finished(it)) {
-		current = (zone_node_t *)*hattrie_iter_val(it);
+	while (!trie_it_finished(it)) {
+		current = (zone_node_t *)*trie_it_val(it);
 
 		result = callback(previous, current, data);
 		if (result == NSEC_NODE_SKIP) {
@@ -189,13 +189,13 @@ int knot_nsec_chain_iterate_create(zone_tree_t *nodes,
 		} else if (result == KNOT_EOK) {
 			previous = current;
 		} else {
-			hattrie_iter_free(it);
+			trie_it_free(it);
 			return result;
 		}
-		hattrie_iter_next(it);
+		trie_it_next(it);
 	}
 
-	hattrie_iter_free(it);
+	trie_it_free(it);
 
 	return result == NSEC_NODE_SKIP ? callback(previous, first, data) :
 	                 callback(current, first, data);
diff --git a/src/knot/dnssec/nsec3-chain.c b/src/knot/dnssec/nsec3-chain.c
index ee65ef8bc82ba7bed3e728ca8069e96d42e7fce4..69b214767fb63fdcda9ba9a1655097b81c9fb282 100644
--- a/src/knot/dnssec/nsec3-chain.c
+++ b/src/knot/dnssec/nsec3-chain.c
@@ -120,10 +120,10 @@ static int copy_signatures(zone_tree_t *from, zone_tree_t *to)
 
 	assert(to);
 
-	hattrie_iter_t *it = hattrie_iter_begin(from);
+	trie_it_t *it = trie_it_begin(from);
 
-	for (/* NOP */; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
-		zone_node_t *node_from = (zone_node_t *)*hattrie_iter_val(it);
+	for (/* NOP */; !trie_it_finished(it); trie_it_next(it)) {
+		zone_node_t *node_from = (zone_node_t *)*trie_it_val(it);
 		zone_node_t *node_to = NULL;
 
 		zone_tree_get(to, node_from->owner, &node_to);
@@ -137,12 +137,12 @@ static int copy_signatures(zone_tree_t *from, zone_tree_t *to)
 
 		int ret = shallow_copy_signature(node_from, node_to);
 		if (ret != KNOT_EOK) {
-			hattrie_iter_free(it);
+			trie_it_free(it);
 			return ret;
 		}
 	}
 
-	hattrie_iter_free(it);
+	trie_it_free(it);
 	return KNOT_EOK;
 }
 
@@ -154,9 +154,9 @@ static void free_nsec3_tree(zone_tree_t *nodes)
 {
 	assert(nodes);
 
-	hattrie_iter_t *it = hattrie_iter_begin(nodes);
-	for (/* NOP */; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
-		zone_node_t *node = (zone_node_t *)*hattrie_iter_val(it);
+	trie_it_t *it = trie_it_begin(nodes);
+	for (/* NOP */; !trie_it_finished(it); trie_it_next(it)) {
+		zone_node_t *node = (zone_node_t *)*trie_it_val(it);
 		// newly allocated NSEC3 nodes
 		knot_rdataset_t *nsec3 = node_rdataset(node, KNOT_RRTYPE_NSEC3);
 		knot_rdataset_t *rrsig = node_rdataset(node, KNOT_RRTYPE_RRSIG);
@@ -165,7 +165,7 @@ static void free_nsec3_tree(zone_tree_t *nodes)
 		node_free(&node, NULL);
 	}
 
-	hattrie_iter_free(it);
+	trie_it_free(it);
 	zone_tree_free(&nodes);
 }
 
@@ -428,9 +428,9 @@ static int create_nsec3_nodes(const zone_contents_t *zone,
 
 	int result = KNOT_EOK;
 
-	hattrie_iter_t *it = hattrie_iter_begin(zone->nodes);
-	while (!hattrie_iter_finished(it)) {
-		zone_node_t *node = (zone_node_t *)*hattrie_iter_val(it);
+	trie_it_t *it = trie_it_begin(zone->nodes);
+	while (!trie_it_finished(it)) {
+		zone_node_t *node = (zone_node_t *)*trie_it_val(it);
 
 		/*!
 		 * Remove possible NSEC from the node. (Do not allow both NSEC
@@ -444,7 +444,7 @@ static int create_nsec3_nodes(const zone_contents_t *zone,
 			node->flags |= NODE_FLAGS_REMOVED_NSEC;
 		}
 		if (node->flags & NODE_FLAGS_NONAUTH || node->flags & NODE_FLAGS_EMPTY) {
-			hattrie_iter_next(it);
+			trie_it_next(it);
 			continue;
 		}
 
@@ -461,10 +461,10 @@ static int create_nsec3_nodes(const zone_contents_t *zone,
 			break;
 		}
 
-		hattrie_iter_next(it);
+		trie_it_next(it);
 	}
 
-	hattrie_iter_free(it);
+	trie_it_free(it);
 
 	return result;
 }
diff --git a/src/knot/dnssec/zone-sign.c b/src/knot/dnssec/zone-sign.c
index 16f548ced052770855f9566a9215db49b6e4181b..867cc811cab012606e4cd89a5ca091274df0f8a1 100644
--- a/src/knot/dnssec/zone-sign.c
+++ b/src/knot/dnssec/zone-sign.c
@@ -615,7 +615,7 @@ typedef struct {
 	const zone_keyset_t *zone_keys;
 	const kdnssec_ctx_t *dnssec_ctx;
 	changeset_t *changeset;
-	hattrie_t *signed_tree;
+	trie_t *signed_tree;
 } changeset_signing_data_t;
 
 /*- private API - DNSKEY handling --------------------------------------------*/
@@ -978,7 +978,7 @@ static int add_rr_type_to_list(const knot_rrset_t *rr, list_t *l)
  *
  * \return KNOT_E*
  */
-static int rr_already_signed(const knot_rrset_t *rrset, hattrie_t *t,
+static int rr_already_signed(const knot_rrset_t *rrset, trie_t *t,
                              bool *rr_signed)
 {
 	assert(rrset);
@@ -987,7 +987,7 @@ static int rr_already_signed(const knot_rrset_t *rrset, hattrie_t *t,
 	// Create a key = RRSet owner converted to sortable format
 	uint8_t lf[KNOT_DNAME_MAXLEN];
 	knot_dname_lf(lf, rrset->owner, NULL);
-	value_t stored_info = (signed_info_t *)hattrie_tryget(t, (char *)lf+1,
+	trie_val_t stored_info = (signed_info_t *)trie_get_try(t, (char *)lf+1,
 	                                                      *lf);
 	if (stored_info == NULL) {
 		// Create new info struct
@@ -1018,7 +1018,7 @@ static int rr_already_signed(const knot_rrset_t *rrset, hattrie_t *t,
 			free(info);
 			return ret;
 		}
-		*hattrie_get(t, (char *)lf+1, *lf) = info;
+		*trie_get_ins(t, (char *)lf+1, *lf) = info;
 	} else {
 		signed_info_t *info = *((signed_info_t **)stored_info);
 		assert(info->type_list);
@@ -1107,7 +1107,7 @@ static int sign_changeset_wrap(knot_rrset_t *chg_rrset, changeset_signing_data_t
  * \param val  Node to free.
  * \param d    Unused.
  */
-static int free_helper_trie_node(value_t *val, void *d)
+static int free_helper_trie_node(trie_val_t *val, void *d)
 {
 	UNUSED(d);
 	signed_info_t *info = (signed_info_t *)*val;
@@ -1126,10 +1126,10 @@ static int free_helper_trie_node(value_t *val, void *d)
  *
  * \param t  Trie to clear.
  */
-static void knot_zone_clear_sorted_changes(hattrie_t *t)
+static void knot_zone_clear_sorted_changes(trie_t *t)
 {
 	if (t) {
-		hattrie_apply_rev(t, free_helper_trie_node, NULL);
+		trie_apply(t, free_helper_trie_node, NULL);
 	}
 }
 
@@ -1257,13 +1257,13 @@ int knot_zone_sign_changeset(const zone_contents_t *zone,
 		return KNOT_EINVAL;
 	}
 
-	// Create args for wrapper function - hattrie for duplicate sigs
+	// Create args for wrapper function - trie for duplicate sigs
 	changeset_signing_data_t args = {
 		.zone = zone,
 		.zone_keys = zone_keys,
 		.dnssec_ctx = dnssec_ctx,
 		.changeset = out_ch,
-		.signed_tree = hattrie_create(NULL)
+		.signed_tree = trie_create(NULL)
 	};
 
 	if (args.signed_tree == NULL) {
@@ -1285,7 +1285,7 @@ int knot_zone_sign_changeset(const zone_contents_t *zone,
 	changeset_iter_clear(&itt);
 
 	knot_zone_clear_sorted_changes(args.signed_tree);
-	hattrie_free(args.signed_tree);
+	trie_free(args.signed_tree);
 
 	return KNOT_EOK;
 }
diff --git a/src/knot/nameserver/axfr.c b/src/knot/nameserver/axfr.c
index b13c58cc5480b3103634575a0dd921361dbd693a..1a1439772853da3e42cdfe9f8a4c9b380e1d0419 100644
--- a/src/knot/nameserver/axfr.c
+++ b/src/knot/nameserver/axfr.c
@@ -37,7 +37,7 @@
 /* AXFR context. @note aliasing the generic xfr_proc */
 struct axfr_proc {
 	struct xfr_proc proc;
-	hattrie_iter_t *i;
+	trie_it_t *i;
 	unsigned cur_rrset;
 };
 
@@ -78,24 +78,24 @@ static int axfr_process_node_tree(knot_pkt_t *pkt, const void *item,
 	struct axfr_proc *axfr = (struct axfr_proc*)state;
 
 	if (axfr->i == NULL) {
-		axfr->i = hattrie_iter_begin((hattrie_t *)item);
+		axfr->i = trie_it_begin((trie_t *)item);
 	}
 
 	/* Put responses. */
 	int ret = KNOT_EOK;
 	zone_node_t *node = NULL;
-	while (!hattrie_iter_finished(axfr->i)) {
-		node = (zone_node_t *)*hattrie_iter_val(axfr->i);
+	while (!trie_it_finished(axfr->i)) {
+		node = (zone_node_t *)*trie_it_val(axfr->i);
 		ret = axfr_put_rrsets(pkt, node, axfr);
 		if (ret != KNOT_EOK) {
 			break;
 		}
-		hattrie_iter_next(axfr->i);
+		trie_it_next(axfr->i);
 	}
 
 	/* Finished all nodes. */
 	if (ret == KNOT_EOK) {
-		hattrie_iter_free(axfr->i);
+		trie_it_free(axfr->i);
 		axfr->i = NULL;
 	}
 	return ret;
@@ -105,7 +105,7 @@ static void axfr_query_cleanup(struct query_data *qdata)
 {
 	struct axfr_proc *axfr = (struct axfr_proc *)qdata->ext;
 
-	hattrie_iter_free(axfr->i);
+	trie_it_free(axfr->i);
 	ptrlist_free(&axfr->proc.nodes, qdata->mm);
 	mm_free(qdata->mm, axfr);
 
diff --git a/src/knot/server/server.c b/src/knot/server/server.c
index 71dad2cd44ff5a1cddae7bc724b65cb567a34529..62c2f265d8becaaa717d4e0585e24811b09faa64 100644
--- a/src/knot/server/server.c
+++ b/src/knot/server/server.c
@@ -616,7 +616,7 @@ int server_reload(server_t *server)
 		// Reset confio reload context.
 		conf()->io.flags = YP_FNONE;
 		if (conf()->io.zones != NULL) {
-			hattrie_clear(conf()->io.zones);
+			trie_clear(conf()->io.zones);
 		}
 	}
 
diff --git a/src/knot/updates/changesets.c b/src/knot/updates/changesets.c
index f68cf36bc6f6ba73d188fc5f241a0334c5a98a9e..2d3125a291f7af69b41b097d326fbb76f0f69de1 100644
--- a/src/knot/updates/changesets.c
+++ b/src/knot/updates/changesets.c
@@ -54,8 +54,8 @@ static void cleanup_iter_list(list_t *l)
 {
 	ptrnode_t *n, *nxt;
 	WALK_LIST_DELSAFE(n, nxt, *l) {
-		hattrie_iter_t *it = (hattrie_iter_t *)n->d;
-		hattrie_iter_free(it);
+		trie_it_t *it = (trie_it_t *)n->d;
+		trie_it_free(it);
 		rem_node(&n->n);
 		free(n);
 	}
@@ -72,12 +72,12 @@ static int changeset_iter_init(changeset_iter_t *ch_it, size_t tries, ...)
 	va_start(args, tries);
 
 	for (size_t i = 0; i < tries; ++i) {
-		hattrie_t *t = va_arg(args, hattrie_t *);
+		trie_t *t = va_arg(args, trie_t *);
 		if (t == NULL) {
 			continue;
 		}
 
-		hattrie_iter_t *it = hattrie_iter_begin(t);
+		trie_it_t *it = trie_it_begin(t);
 		if (it == NULL) {
 			cleanup_iter_list(&ch_it->iters);
 			va_end(args);
@@ -97,27 +97,27 @@ static int changeset_iter_init(changeset_iter_t *ch_it, size_t tries, ...)
 }
 
 /*! \brief Gets next node from trie iterators. */
-static void iter_next_node(changeset_iter_t *ch_it, hattrie_iter_t *t_it)
+static void iter_next_node(changeset_iter_t *ch_it, trie_it_t *t_it)
 {
-	assert(!hattrie_iter_finished(t_it));
+	assert(!trie_it_finished(t_it));
 	// Get next node, but not for the very first call.
 	if (ch_it->node) {
-		hattrie_iter_next(t_it);
+		trie_it_next(t_it);
 	}
-	if (hattrie_iter_finished(t_it)) {
+	if (trie_it_finished(t_it)) {
 		ch_it->node = NULL;
 		return;
 	}
 
-	ch_it->node = (zone_node_t *)*hattrie_iter_val(t_it);
+	ch_it->node = (zone_node_t *)*trie_it_val(t_it);
 	assert(ch_it->node);
 	while (ch_it->node && ch_it->node->rrset_count == 0) {
 		// Skip empty non-terminals.
-		hattrie_iter_next(t_it);
-		if (hattrie_iter_finished(t_it)) {
+		trie_it_next(t_it);
+		if (trie_it_finished(t_it)) {
 			ch_it->node = NULL;
 		} else {
-			ch_it->node = (zone_node_t *)*hattrie_iter_val(t_it);
+			ch_it->node = (zone_node_t *)*trie_it_val(t_it);
 			assert(ch_it->node);
 		}
 	}
@@ -126,12 +126,12 @@ static void iter_next_node(changeset_iter_t *ch_it, hattrie_iter_t *t_it)
 }
 
 /*! \brief Gets next RRSet from trie iterators. */
-static knot_rrset_t get_next_rr(changeset_iter_t *ch_it, hattrie_iter_t *t_it)
+static knot_rrset_t get_next_rr(changeset_iter_t *ch_it, trie_it_t *t_it)
 {
 	if (ch_it->node == NULL || ch_it->node_pos == ch_it->node->rrset_count) {
 		iter_next_node(ch_it, t_it);
 		if (ch_it->node == NULL) {
-			assert(hattrie_iter_finished(t_it));
+			assert(trie_it_finished(t_it));
 			knot_rrset_t rr;
 			knot_rrset_init_empty(&rr);
 			return rr;
@@ -458,8 +458,8 @@ knot_rrset_t changeset_iter_next(changeset_iter_t *it)
 	knot_rrset_t rr;
 	knot_rrset_init_empty(&rr);
 	WALK_LIST(n, it->iters) {
-		hattrie_iter_t *t_it = (hattrie_iter_t *)n->d;
-		if (hattrie_iter_finished(t_it)) {
+		trie_it_t *t_it = (trie_it_t *)n->d;
+		if (trie_it_finished(t_it)) {
 			continue;
 		}
 
diff --git a/src/knot/updates/zone-update.c b/src/knot/updates/zone-update.c
index d8da3c403aee7a18ef8a770e60d0a219c53c118e..71960115c4fae9f31d42caa9bbd85ec5882ad207 100644
--- a/src/knot/updates/zone-update.c
+++ b/src/knot/updates/zone-update.c
@@ -634,27 +634,27 @@ static int iter_init_tree_iters(zone_update_iter_t *it, zone_update_t *update,
 
 	/* Begin iteration. We can safely assume _contents is a valid pointer. */
 	zone_tree_t *tree = nsec3 ? _contents->nsec3_nodes : _contents->nodes;
-	it->tree_it = hattrie_iter_begin(tree);
+	it->tree_it = trie_it_begin(tree);
 	if (it->tree_it == NULL) {
 		return KNOT_ENOMEM;
 	}
 
-	it->cur_node = (zone_node_t *)(*hattrie_iter_val(it->tree_it));
+	it->cur_node = (zone_node_t *)(*trie_it_val(it->tree_it));
 
 	return KNOT_EOK;
 }
 
 static int iter_get_next_node(zone_update_iter_t *it)
 {
-	hattrie_iter_next(it->tree_it);
-	if (hattrie_iter_finished(it->tree_it)) {
-		hattrie_iter_free(it->tree_it);
+	trie_it_next(it->tree_it);
+	if (trie_it_finished(it->tree_it)) {
+		trie_it_free(it->tree_it);
 		it->tree_it = NULL;
 		it->cur_node = NULL;
 		return KNOT_ENOENT;
 	}
 
-	it->cur_node = (zone_node_t *)(*hattrie_iter_val(it->tree_it));
+	it->cur_node = (zone_node_t *)(*trie_it_val(it->tree_it));
 
 	return KNOT_EOK;
 }
@@ -670,7 +670,7 @@ static int iter_init(zone_update_iter_t *it, zone_update_t *update, const bool n
 		return ret;
 	}
 
-	it->cur_node = (zone_node_t *)(*hattrie_iter_val(it->tree_it));
+	it->cur_node = (zone_node_t *)(*trie_it_val(it->tree_it));
 
 	return KNOT_EOK;
 }
@@ -737,7 +737,7 @@ void zone_update_iter_finish(zone_update_iter_t *it)
 		return;
 	}
 
-	hattrie_iter_free(it->tree_it);
+	trie_it_free(it->tree_it);
 }
 
 bool zone_update_no_change(zone_update_t *update)
diff --git a/src/knot/updates/zone-update.h b/src/knot/updates/zone-update.h
index 69924b716bb08230d5dc3bd50ed3d1c58edd7741..07aa131a6d445340d564634c26aaffed99fa3b98 100644
--- a/src/knot/updates/zone-update.h
+++ b/src/knot/updates/zone-update.h
@@ -43,7 +43,7 @@ typedef struct zone_update {
 
 typedef struct {
 	zone_update_t *update;          /*!< The update we're iterating over. */
-	hattrie_iter_t *tree_it;        /*!< Iterator for the new zone. */
+	trie_it_t *tree_it;             /*!< Iterator for the new zone. */
 	const zone_node_t *cur_node;    /*!< Current node in the new zone. */
 	bool nsec3;                     /*!< Set when we're using the NSEC3 node tree. */
 } zone_update_iter_t;
diff --git a/src/knot/zone/contents.c b/src/knot/zone/contents.c
index 0b53747f47bb4fefd74e2c57dd1fdf7d77281718..704b5d3305fdbc46daa23c4fe1efd85c198359b0 100644
--- a/src/knot/zone/contents.c
+++ b/src/knot/zone/contents.c
@@ -21,7 +21,7 @@
 #include "knot/common/log.h"
 #include "knot/dnssec/zone-nsec.h"
 #include "libknot/libknot.h"
-#include "contrib/hat-trie/hat-trie.h"
+#include "contrib/qp-trie/trie.h"
 #include "contrib/macros.h"
 
 typedef struct {
@@ -652,7 +652,7 @@ static int remove_rr(zone_contents_t *z, const knot_rrset_t *rr,
 
 static int recreate_normal_tree(const zone_contents_t *z, zone_contents_t *out)
 {
-	out->nodes = hattrie_create(NULL);
+	out->nodes = trie_create(NULL);
 	if (out->nodes == NULL) {
 		return KNOT_ENOMEM;
 	}
@@ -672,68 +672,68 @@ static int recreate_normal_tree(const zone_contents_t *z, zone_contents_t *out)
 
 	out->apex = apex_cpy;
 
-	hattrie_iter_t *itt = hattrie_iter_begin(z->nodes);
+	trie_it_t *itt = trie_it_begin(z->nodes);
 	if (itt == NULL) {
 		return KNOT_ENOMEM;
 	}
 
-	while (!hattrie_iter_finished(itt)) {
-		const zone_node_t *to_cpy = (zone_node_t *)*hattrie_iter_val(itt);
+	while (!trie_it_finished(itt)) {
+		const zone_node_t *to_cpy = (zone_node_t *)*trie_it_val(itt);
 		if (to_cpy == z->apex) {
 			// Inserted already.
-			hattrie_iter_next(itt);
+			trie_it_next(itt);
 			continue;
 		}
 		zone_node_t *to_add = node_shallow_copy(to_cpy, NULL);
 		if (to_add == NULL) {
-			hattrie_iter_free(itt);
+			trie_it_free(itt);
 			return KNOT_ENOMEM;
 		}
 
 		int ret = add_node(out, to_add, true);
 		if (ret != KNOT_EOK) {
 			node_free(&to_add, NULL);
-			hattrie_iter_free(itt);
+			trie_it_free(itt);
 			return ret;
 		}
-		hattrie_iter_next(itt);
+		trie_it_next(itt);
 	}
 
-	hattrie_iter_free(itt);
+	trie_it_free(itt);
 
 	return KNOT_EOK;
 }
 
 static int recreate_nsec3_tree(const zone_contents_t *z, zone_contents_t *out)
 {
-	out->nsec3_nodes = hattrie_create(NULL);
+	out->nsec3_nodes = trie_create(NULL);
 	if (out->nsec3_nodes == NULL) {
 		return KNOT_ENOMEM;
 	}
 
-	hattrie_iter_t *itt = hattrie_iter_begin(z->nsec3_nodes);
+	trie_it_t *itt = trie_it_begin(z->nsec3_nodes);
 	if (itt == NULL) {
 		return KNOT_ENOMEM;
 	}
-	while (!hattrie_iter_finished(itt)) {
-		const zone_node_t *to_cpy = (zone_node_t *)*hattrie_iter_val(itt);
+	while (!trie_it_finished(itt)) {
+		const zone_node_t *to_cpy = (zone_node_t *)*trie_it_val(itt);
 		zone_node_t *to_add = node_shallow_copy(to_cpy, NULL);
 		if (to_add == NULL) {
-			hattrie_iter_free(itt);
+			trie_it_free(itt);
 			return KNOT_ENOMEM;
 		}
 
 		int ret = add_nsec3_node(out, to_add);
 		if (ret != KNOT_EOK) {
-			hattrie_iter_free(itt);
+			trie_it_free(itt);
 			node_free(&to_add, NULL);
 			return ret;
 		}
 
-		hattrie_iter_next(itt);
+		trie_it_next(itt);
 	}
 
-	hattrie_iter_free(itt);
+	trie_it_free(itt);
 
 	return KNOT_EOK;
 }
diff --git a/src/knot/zone/zone-tree.c b/src/knot/zone/zone-tree.c
index 47a559bfab881c672bf2ba80c3e70264c7b7c097..e949ebe9e33d5cb7a6ef355f48f9ca334e47c3b4 100644
--- a/src/knot/zone/zone-tree.c
+++ b/src/knot/zone/zone-tree.c
@@ -24,7 +24,7 @@
 
 zone_tree_t* zone_tree_create()
 {
-	return hattrie_create(NULL);
+	return trie_create(NULL);
 }
 
 size_t zone_tree_count(const zone_tree_t *tree)
@@ -33,7 +33,7 @@ size_t zone_tree_count(const zone_tree_t *tree)
 		return 0;
 	}
 
-	return hattrie_weight(tree);
+	return trie_weight(tree);
 }
 
 int zone_tree_is_empty(const zone_tree_t *tree)
@@ -51,7 +51,7 @@ int zone_tree_insert(zone_tree_t *tree, zone_node_t *node)
 	uint8_t lf[KNOT_DNAME_MAXLEN];
 	knot_dname_lf(lf, node->owner, NULL);
 
-	*hattrie_get(tree, (char*)lf+1, *lf) = node;
+	*trie_get_ins(tree, (char*)lf+1, *lf) = node;
 	return KNOT_EOK;
 }
 
@@ -69,7 +69,7 @@ int zone_tree_get(zone_tree_t *tree, const knot_dname_t *owner,
 	uint8_t lf[KNOT_DNAME_MAXLEN];
 	knot_dname_lf(lf, owner, NULL);
 
-	value_t *val = hattrie_tryget(tree, (char*)lf+1, *lf);
+	trie_val_t *val = trie_get_try(tree, (char*)lf+1, *lf);
 	if (val == NULL) {
 		*found = NULL;
 	} else {
@@ -95,8 +95,8 @@ int zone_tree_get_less_or_equal(zone_tree_t *tree,
 	uint8_t lf[KNOT_DNAME_MAXLEN];
 	knot_dname_lf(lf, owner, NULL);
 
-	value_t *fval = NULL;
-	int ret = hattrie_find_leq(tree, (char*)lf+1, *lf, &fval);
+	trie_val_t *fval = NULL;
+	int ret = trie_get_leq(tree, (char*)lf+1, *lf, &fval);
 	if (fval) {
 		*found = (zone_node_t *)(*fval);
 	}
@@ -116,11 +116,11 @@ int zone_tree_get_less_or_equal(zone_tree_t *tree,
 		 * cases like NSEC3, there is no such sort of thing (name wise).
 		 */
 		/*! \todo We could store rightmost node in zonetree probably. */
-		hattrie_iter_t *i = hattrie_iter_begin(tree);
-		*previous = *(zone_node_t **)hattrie_iter_val(i); /* leftmost */
+		trie_it_t *i = trie_it_begin(tree);
+		*previous = *(zone_node_t **)trie_it_val(i); /* leftmost */
 		*previous = (*previous)->prev; /* rightmost */
 		*found = NULL;
-		hattrie_iter_free(i);
+		trie_it_free(i);
 	}
 
 	return exact_match;
@@ -141,14 +141,14 @@ int zone_tree_remove(zone_tree_t *tree,
 	uint8_t lf[KNOT_DNAME_MAXLEN];
 	knot_dname_lf(lf, owner, NULL);
 
-	value_t *rval = hattrie_tryget(tree, (char*)lf+1, *lf);
+	trie_val_t *rval = trie_get_try(tree, (char*)lf+1, *lf);
 	if (rval == NULL) {
 		return KNOT_ENOENT;
 	} else {
 		*removed = (zone_node_t *)(*rval);
 	}
 
-	hattrie_del(tree, (char*)lf+1, *lf, NULL);
+	trie_del(tree, (char*)lf+1, *lf, NULL);
 	return KNOT_EOK;
 }
 
@@ -201,7 +201,7 @@ int zone_tree_apply(zone_tree_t *tree, zone_tree_apply_cb_t function, void *data
 		return KNOT_EOK;
 	}
 
-	return hattrie_apply_rev(tree, (int (*)(value_t *, void *))function, data);
+	return trie_apply(tree, (int (*)(trie_val_t *, void *))function, data);
 }
 
 void zone_tree_free(zone_tree_t **tree)
@@ -209,7 +209,7 @@ void zone_tree_free(zone_tree_t **tree)
 	if (tree == NULL || *tree == NULL) {
 		return;
 	}
-	hattrie_free(*tree);
+	trie_free(*tree);
 	*tree = NULL;
 }
 
diff --git a/src/knot/zone/zone-tree.h b/src/knot/zone/zone-tree.h
index ee742b63d55aa9db3cb1f7a05361914c2f948b74..fe037e2047fcf51b14413d737aff11f5de94e575 100644
--- a/src/knot/zone/zone-tree.h
+++ b/src/knot/zone/zone-tree.h
@@ -24,10 +24,10 @@
 
 #pragma once
 
-#include "contrib/hat-trie/hat-trie.h"
+#include "contrib/qp-trie/trie.h"
 #include "knot/zone/node.h"
 
-typedef hattrie_t zone_tree_t;
+typedef trie_t zone_tree_t;
 
 /*!
  * \brief Signature of callback for zone apply functions.
diff --git a/src/knot/zone/zonedb-load.c b/src/knot/zone/zonedb-load.c
index 2935502e8f74cda6f0e5840d17fb92783d715be5..e53eec3699dfc38b11971fd27e0902f993825e20 100644
--- a/src/knot/zone/zonedb-load.c
+++ b/src/knot/zone/zonedb-load.c
@@ -273,25 +273,25 @@ static zone_t *create_zone(conf_t *conf, const knot_dname_t *name, server_t *ser
 	}
 }
 
-static void mark_changed_zones(knot_zonedb_t *zonedb, hattrie_t *changed)
+static void mark_changed_zones(knot_zonedb_t *zonedb, trie_t *changed)
 {
 	if (changed == NULL) {
 		return;
 	}
 
-	hattrie_iter_t *it = hattrie_iter_begin(changed);
-	for (; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
+	trie_it_t *it = trie_it_begin(changed);
+	for (; !trie_it_finished(it); trie_it_next(it)) {
 		const knot_dname_t *name =
-			(const knot_dname_t *)hattrie_iter_key(it, NULL);
+			(const knot_dname_t *)trie_it_key(it, NULL);
 
 		zone_t *zone = knot_zonedb_find(zonedb, name);
 		if (zone != NULL) {
-			conf_io_type_t type = (conf_io_type_t)(*hattrie_iter_val(it));
+			conf_io_type_t type = (conf_io_type_t)(*trie_it_val(it));
 			assert(!(type & CONF_IO_TSET));
 			zone->change_type = type;
 		}
 	}
-	hattrie_iter_free(it);
+	trie_it_free(it);
 }
 
 /*!
diff --git a/src/libknot/db/db_trie.c b/src/libknot/db/db_trie.c
index 8f1141812dc1f817f4ff32e01f43bdc5e9b6762d..d0fbb0ca2c47d14326f1df629c4eef746f34d5f9 100644
--- a/src/libknot/db/db_trie.c
+++ b/src/libknot/db/db_trie.c
@@ -19,7 +19,7 @@
 #include "libknot/attribute.h"
 #include "libknot/errcode.h"
 #include "libknot/db/db_trie.h"
-#include "contrib/hat-trie/hat-trie.h"
+#include "contrib/qp-trie/trie.h"
 #include "contrib/macros.h"
 #include "contrib/mempattern.h"
 
@@ -31,7 +31,7 @@ static int init(knot_db_t **db, knot_mm_t *mm, void *arg)
 
 	struct knot_db_trie_opts *opts = arg;
 	UNUSED(opts);
-	hattrie_t *trie = hattrie_create(mm);
+	trie_t *trie = trie_create(mm);
 	if (!trie) {
 		return KNOT_ENOMEM;
 	}
@@ -43,7 +43,7 @@ static int init(knot_db_t **db, knot_mm_t *mm, void *arg)
 
 static void deinit(knot_db_t *db)
 {
-	hattrie_free((hattrie_t *)db);
+	trie_free((trie_t *)db);
 }
 
 static int txn_begin(knot_db_t *db, knot_db_txn_t *txn, unsigned flags)
@@ -64,25 +64,25 @@ static void txn_abort(knot_db_txn_t *txn)
 
 static int count(knot_db_txn_t *txn)
 {
-	return hattrie_weight((hattrie_t *)txn->db);
+	return trie_weight((trie_t *)txn->db);
 }
 
 static int clear(knot_db_txn_t *txn)
 {
-	hattrie_clear((hattrie_t *)txn->db);
+	trie_clear((trie_t *)txn->db);
 
 	return KNOT_EOK;
 }
 
 static int find(knot_db_txn_t *txn, knot_db_val_t *key, knot_db_val_t *val, unsigned flags)
 {
-	value_t *ret = hattrie_tryget((hattrie_t *)txn->db, key->data, key->len);
+	trie_val_t *ret = trie_get_try((trie_t *)txn->db, key->data, key->len);
 	if (ret == NULL) {
 		return KNOT_ENOENT;
 	}
 
 	val->data = *ret;
-	val->len  = sizeof(value_t); /* Trie doesn't support storing length. */
+	val->len  = sizeof(trie_val_t); /* Trie doesn't support storing length. */
 	return KNOT_EOK;
 }
 
@@ -93,7 +93,7 @@ static int insert(knot_db_txn_t *txn, knot_db_val_t *key, knot_db_val_t *val, un
 		return KNOT_ENOTSUP;
 	}
 
-	value_t *ret = hattrie_get((hattrie_t *)txn->db, key->data, key->len);
+	trie_val_t *ret = trie_get_ins((trie_t *)txn->db, key->data, key->len);
 	if (ret == NULL) {
 		return KNOT_ENOMEM;
 	}
@@ -104,7 +104,7 @@ static int insert(knot_db_txn_t *txn, knot_db_val_t *key, knot_db_val_t *val, un
 
 static int del(knot_db_txn_t *txn, knot_db_val_t *key)
 {
-	return hattrie_del((hattrie_t *)txn->db, key->data, key->len, NULL);
+	return trie_del((trie_t *)txn->db, key->data, key->len, NULL);
 }
 
 static knot_db_iter_t *iter_begin(knot_db_txn_t *txn, unsigned flags)
@@ -116,7 +116,7 @@ static knot_db_iter_t *iter_begin(knot_db_txn_t *txn, unsigned flags)
 		return NULL;
 	}
 
-	return hattrie_iter_begin((hattrie_t *)txn->db);
+	return trie_it_begin((trie_t *)txn->db);
 }
 
 static knot_db_iter_t *iter_seek(knot_db_iter_t *iter, knot_db_val_t *key, unsigned flags)
@@ -127,9 +127,9 @@ static knot_db_iter_t *iter_seek(knot_db_iter_t *iter, knot_db_val_t *key, unsig
 
 static knot_db_iter_t *iter_next(knot_db_iter_t *iter)
 {
-	hattrie_iter_next((hattrie_iter_t *)iter);
-	if (hattrie_iter_finished((hattrie_iter_t *)iter)) {
-		hattrie_iter_free((hattrie_iter_t *)iter);
+	trie_it_next((trie_it_t *)iter);
+	if (trie_it_finished((trie_it_t *)iter)) {
+		trie_it_free((trie_it_t *)iter);
 		return NULL;
 	}
 
@@ -138,7 +138,7 @@ static knot_db_iter_t *iter_next(knot_db_iter_t *iter)
 
 static int iter_key(knot_db_iter_t *iter, knot_db_val_t *val)
 {
-	val->data = (void *)hattrie_iter_key((hattrie_iter_t *)iter, &val->len);
+	val->data = (void *)trie_it_key((trie_it_t *)iter, &val->len);
 	if (val->data == NULL) {
 		return KNOT_ENOENT;
 	}
@@ -148,26 +148,26 @@ static int iter_key(knot_db_iter_t *iter, knot_db_val_t *val)
 
 static int iter_val(knot_db_iter_t *iter, knot_db_val_t *val)
 {
-	value_t *ret = hattrie_iter_val((hattrie_iter_t *)iter);
+	trie_val_t *ret = trie_it_val((trie_it_t *)iter);
 	if (ret == NULL) {
 		return KNOT_ENOENT;
 	}
 
 	val->data = *ret;
-	val->len  = sizeof(value_t);
+	val->len  = sizeof(trie_val_t);
 	return KNOT_EOK;
 }
 
 static void iter_finish(knot_db_iter_t *iter)
 {
-	hattrie_iter_free((hattrie_iter_t *)iter);
+	trie_it_free((trie_it_t *)iter);
 }
 
 _public_
 const knot_db_api_t *knot_db_trie_api(void)
 {
 	static const knot_db_api_t api = {
-		"hattrie",
+		"trie",
 		init, deinit,
 		txn_begin, txn_commit, txn_abort,
 		count, clear, find, insert, del,
diff --git a/src/utils/common/lookup.c b/src/utils/common/lookup.c
index 7e84962c352735b914b09f79567e2d353be5ac76..a51d0f155398dd679ffa8b659578fd6acb756c3d 100644
--- a/src/utils/common/lookup.c
+++ b/src/utils/common/lookup.c
@@ -29,7 +29,7 @@ int lookup_init(lookup_t *lookup)
 	memset(lookup, 0, sizeof(*lookup));
 
 	mm_ctx_mempool(&lookup->mm, MM_DEFAULT_BLKSIZE);
-	lookup->trie = hattrie_create(&lookup->mm);
+	lookup->trie = trie_create(&lookup->mm);
 	if (lookup->trie == NULL) {
 		mp_delete(lookup->mm.ctx);
 		return KNOT_ENOMEM;
@@ -53,7 +53,7 @@ static void reset_output(lookup_t *lookup)
 	mm_free(&lookup->mm, lookup->iter.first_key);
 	lookup->iter.first_key = NULL;
 
-	hattrie_iter_free(lookup->iter.it);
+	trie_it_free(lookup->iter.it);
 	lookup->iter.it = NULL;
 }
 
@@ -65,7 +65,7 @@ void lookup_deinit(lookup_t *lookup)
 
 	reset_output(lookup);
 
-	hattrie_free(lookup->trie);
+	trie_free(lookup->trie);
 	mp_delete(lookup->mm.ctx);
 }
 
@@ -80,7 +80,7 @@ int lookup_insert(lookup_t *lookup, const char *str, void *data)
 		return KNOT_EINVAL;
 	}
 
-	value_t *val = hattrie_get(lookup->trie, str, str_len);
+	trie_val_t *val = trie_get_ins(lookup->trie, str, str_len);
 	if (val == NULL) {
 		return KNOT_ENOMEM;
 	}
@@ -118,10 +118,10 @@ int lookup_search(lookup_t *lookup, const char *str, size_t str_len)
 	reset_output(lookup);
 
 	size_t new_len = 0;
-	hattrie_iter_t *it = hattrie_iter_begin(lookup->trie);
-	for (; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
+	trie_it_t *it = trie_it_begin(lookup->trie);
+	for (; !trie_it_finished(it); trie_it_next(it)) {
 		size_t len;
-		const char *key = hattrie_iter_key(it, &len);
+		const char *key = trie_it_key(it, &len);
 
 		// Compare with a shorter key.
 		if (len < str_len) {
@@ -144,7 +144,7 @@ int lookup_search(lookup_t *lookup, const char *str, size_t str_len)
 				if (ret != KNOT_EOK) {
 					break;
 				}
-				lookup->found.data = *hattrie_iter_val(it);
+				lookup->found.data = *trie_it_val(it);
 				new_len = len;
 			// Another candidate.
 			} else if (new_len > str_len) {
@@ -160,7 +160,7 @@ int lookup_search(lookup_t *lookup, const char *str, size_t str_len)
 			break;
 		}
 	}
-	hattrie_iter_free(it);
+	trie_it_free(it);
 
 	switch (lookup->iter.count) {
 	case 0:
@@ -187,37 +187,37 @@ void lookup_list(lookup_t *lookup)
 	}
 
 	if (lookup->iter.it != NULL) {
-		if (hattrie_iter_finished(lookup->iter.it)) {
-			hattrie_iter_free(lookup->iter.it);
+		if (trie_it_finished(lookup->iter.it)) {
+			trie_it_free(lookup->iter.it);
 			lookup->iter.it = NULL;
 			return;
 		}
 
-		hattrie_iter_next(lookup->iter.it);
+		trie_it_next(lookup->iter.it);
 
 		size_t len;
-		const char *key = hattrie_iter_key(lookup->iter.it, &len);
+		const char *key = trie_it_key(lookup->iter.it, &len);
 
 		int ret = set_key(lookup, &lookup->found.key, key, len);
 		if (ret == KNOT_EOK) {
-			lookup->found.data = *hattrie_iter_val(lookup->iter.it);
+			lookup->found.data = *trie_it_val(lookup->iter.it);
 		}
 		return;
 	}
 
-	lookup->iter.it = hattrie_iter_begin(lookup->trie);
-	while (!hattrie_iter_finished(lookup->iter.it)) {
+	lookup->iter.it = trie_it_begin(lookup->trie);
+	while (!trie_it_finished(lookup->iter.it)) {
 		size_t len;
-		const char *key = hattrie_iter_key(lookup->iter.it, &len);
+		const char *key = trie_it_key(lookup->iter.it, &len);
 
 		if (memcmp(key, lookup->iter.first_key, len) == 0) {
 			int ret = set_key(lookup, &lookup->found.key, key, len);
 			if (ret == KNOT_EOK) {
-				lookup->found.data = *hattrie_iter_val(lookup->iter.it);
+				lookup->found.data = *trie_it_val(lookup->iter.it);
 			}
 			break;
 		}
-		hattrie_iter_next(lookup->iter.it);
+		trie_it_next(lookup->iter.it);
 	}
 }
 
diff --git a/src/utils/common/lookup.h b/src/utils/common/lookup.h
index 3bd33084c2d0dc79939c9bb2d1194eef27de33a0..a8eb065fa87c2832bac8a469a49f034bfb7504b8 100644
--- a/src/utils/common/lookup.h
+++ b/src/utils/common/lookup.h
@@ -27,14 +27,14 @@
 #include <histedit.h>
 
 #include "libknot/mm_ctx.h"
-#include "contrib/hat-trie/hat-trie.h"
+#include "contrib/qp-trie/trie.h"
 
 /*! Lookup context. */
 typedef struct {
 	/*! Memory pool context. */
 	knot_mm_t mm;
-	/*! Main hat-trie storage. */
-	hattrie_t *trie;
+	/*! Main trie storage. */
+	trie_t *trie;
 
 	/*! Current (iteration) data context. */
 	struct {
@@ -51,7 +51,7 @@ typedef struct {
 		/*! The first possibility. */
 		char *first_key;
 		/*! Hat-trie iterator. */
-		hattrie_iter_t *it;
+		trie_it_t *it;
 	} iter;
 } lookup_t;
 
diff --git a/src/utils/knot1to2/cf-parse.tab.c b/src/utils/knot1to2/cf-parse.tab.c
index 636066e8a656c694d690d53347ea3ff641a045f0..6e493d693d6df612dc89e3a53623d008df58c10d 100644
--- a/src/utils/knot1to2/cf-parse.tab.c
+++ b/src/utils/knot1to2/cf-parse.tab.c
@@ -234,7 +234,7 @@ static void if_add(void *scanner, const char *key, const char *value)
 	conf_extra_t *extra = cf_get_extra(scanner);
 
 	if (extra->run == S_FIRST) {
-		*hattrie_get(extra->share->ifaces, key, strlen(key)) = strdup(value);
+		*trie_get_ins(extra->share->ifaces, key, strlen(key)) = strdup(value);
 	}
 }
 
@@ -243,7 +243,7 @@ static const char* if_get(void *scanner, int run, const char *key)
 	conf_extra_t *extra = cf_get_extra(scanner);
 
 	if (extra->run == run) {
-		return *hattrie_get(extra->share->ifaces, key, strlen(key));
+		return *trie_get_ins(extra->share->ifaces, key, strlen(key));
 	}
 
 	return NULL;
@@ -279,20 +279,20 @@ static void acl_next(void *scanner, const char *value)
 {
 	conf_extra_t *extra = cf_get_extra(scanner);
 
-	hattrie_t **trie = (hattrie_t **)hattrie_tryget(extra->share->groups,
+	trie_t **trie = (trie_t **)trie_get_try(extra->share->groups,
 	                                                value, strlen(value));
 
 	if (extra->run == S_FIRST) {
 		if (trie != NULL) {
-			hattrie_iter_t *it = hattrie_iter_begin(*trie);
-			for (; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
+			trie_it_t *it = trie_it_begin(*trie);
+			for (; !trie_it_finished(it); trie_it_next(it)) {
 				size_t len = 0;
-				const char *data = hattrie_iter_key(it, &len);
-				*hattrie_get(extra->current_trie, data, len) = NULL;
+				const char *data = trie_it_key(it, &len);
+				*trie_get_ins(extra->current_trie, data, len) = NULL;
 			}
-			hattrie_iter_free(it);
+			trie_it_free(it);
 		} else {
-			*hattrie_get(extra->current_trie, value, strlen(value)) = NULL;
+			*trie_get_ins(extra->current_trie, value, strlen(value)) = NULL;
 		}
 	}
 
@@ -306,10 +306,10 @@ static void acl_next(void *scanner, const char *value)
 
 	if (trie != NULL) {
 		bool init = true;
-		hattrie_iter_t *it = hattrie_iter_begin(*trie);
-		for (; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
+		trie_it_t *it = trie_it_begin(*trie);
+		for (; !trie_it_finished(it); trie_it_next(it)) {
 			size_t len = 0;
-			const char *data = hattrie_iter_key(it, &len);
+			const char *data = trie_it_key(it, &len);
 			if (init) {
 				init = false;
 			} else {
@@ -318,7 +318,7 @@ static void acl_next(void *scanner, const char *value)
 			f_val(scanner, extra->run, false, "%s", _str);
 			f_val(scanner, extra->run, false, "%.*s", (int)len, data);
 		}
-		hattrie_iter_free(it);
+		trie_it_free(it);
 	} else {
 		f_val(scanner, extra->run, false, "%s", _str);
 		f_val(scanner, extra->run, false, "%s", value);
@@ -336,17 +336,17 @@ static void acl_end(void *scanner)
 static bool is_acl(void *scanner, const char *str) {
 	conf_extra_t *extra = cf_get_extra(scanner);
 
-	return hattrie_tryget(extra->share->acl_xfer, str, strlen(str))    != NULL ||
-	       hattrie_tryget(extra->share->acl_notify, str, strlen(str))  != NULL ||
-	       hattrie_tryget(extra->share->acl_update, str, strlen(str))  != NULL;
+	return trie_get_try(extra->share->acl_xfer, str, strlen(str))    != NULL ||
+	       trie_get_try(extra->share->acl_notify, str, strlen(str))  != NULL ||
+	       trie_get_try(extra->share->acl_update, str, strlen(str))  != NULL;
 }
 
 static bool have_acl(void *scanner) {
 	conf_extra_t *extra = cf_get_extra(scanner);
 
-	return (hattrie_weight(extra->share->acl_xfer) +
-	        hattrie_weight(extra->share->acl_notify) +
-	        hattrie_weight(extra->share->acl_update)) > 0;
+	return (trie_weight(extra->share->acl_xfer) +
+	        trie_weight(extra->share->acl_notify) +
+	        trie_weight(extra->share->acl_update)) > 0;
 }
 
 static char *acl_actions(void *scanner, const char *str) {
@@ -357,15 +357,15 @@ static char *acl_actions(void *scanner, const char *str) {
 
 	strlcpy(actions, "[", sizeof(actions));
 
-	if (hattrie_tryget(extra->share->acl_xfer, str, strlen(str)) != NULL) {
+	if (trie_get_try(extra->share->acl_xfer, str, strlen(str)) != NULL) {
 		strlcat(actions, _first ? "" : ", ", sizeof(actions)); _first = false;
 		strlcat(actions, "transfer", sizeof(actions));
 	}
-	if (hattrie_tryget(extra->share->acl_notify, str, strlen(str)) != NULL) {
+	if (trie_get_try(extra->share->acl_notify, str, strlen(str)) != NULL) {
 		strlcat(actions, _first ? "" : ", ", sizeof(actions)); _first = false;
 		strlcat(actions, "notify", sizeof(actions));
 	}
-	if (hattrie_tryget(extra->share->acl_update, str, strlen(str)) != NULL) {
+	if (trie_get_try(extra->share->acl_update, str, strlen(str)) != NULL) {
 		strlcat(actions, _first ? "" : ", ", sizeof(actions)); _first = false;
 		strlcat(actions, "update", sizeof(actions));
 	}
@@ -380,10 +380,10 @@ static void grp_init(void *scanner, const char *name)
 	conf_extra_t *extra = cf_get_extra(scanner);
 
 	if (extra->run == S_FIRST) {
-		hattrie_t **trie = (hattrie_t **)hattrie_get(extra->share->groups,
+		trie_t **trie = (trie_t **)trie_get_ins(extra->share->groups,
 		                                             name, strlen(name));
 		if (*trie == NULL) {
-			*trie = hattrie_create(NULL);
+			*trie = trie_create(NULL);
 		}
 		extra->current_trie = *trie;
 	}
@@ -394,7 +394,7 @@ static void grp_add(void *scanner, const char *value)
 	conf_extra_t *extra = cf_get_extra(scanner);
 
 	if (extra->run == S_FIRST) {
-		*hattrie_get(extra->current_trie, value, strlen(value)) = NULL;
+		*trie_get_ins(extra->current_trie, value, strlen(value)) = NULL;
 	}
 }
 
diff --git a/src/utils/knot1to2/cf-parse.y b/src/utils/knot1to2/cf-parse.y
index 7c0732500b5820daadfccbefa70a06112e430b0d..fa5d0e499e592ddd11c687adaa24fd2f3a81b53d 100644
--- a/src/utils/knot1to2/cf-parse.y
+++ b/src/utils/knot1to2/cf-parse.y
@@ -178,7 +178,7 @@ static void if_add(void *scanner, const char *key, const char *value)
 	conf_extra_t *extra = cf_get_extra(scanner);
 
 	if (extra->run == S_FIRST) {
-		*hattrie_get(extra->share->ifaces, key, strlen(key)) = strdup(value);
+		*trie_get_ins(extra->share->ifaces, key, strlen(key)) = strdup(value);
 	}
 }
 
@@ -187,7 +187,7 @@ static const char* if_get(void *scanner, int run, const char *key)
 	conf_extra_t *extra = cf_get_extra(scanner);
 
 	if (extra->run == run) {
-		return *hattrie_get(extra->share->ifaces, key, strlen(key));
+		return *trie_get_ins(extra->share->ifaces, key, strlen(key));
 	}
 
 	return NULL;
@@ -223,20 +223,20 @@ static void acl_next(void *scanner, const char *value)
 {
 	conf_extra_t *extra = cf_get_extra(scanner);
 
-	hattrie_t **trie = (hattrie_t **)hattrie_tryget(extra->share->groups,
+	trie_t **trie = (trie_t **)trie_get_try(extra->share->groups,
 	                                                value, strlen(value));
 
 	if (extra->run == S_FIRST) {
 		if (trie != NULL) {
-			hattrie_iter_t *it = hattrie_iter_begin(*trie);
-			for (; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
+			trie_it_t *it = trie_it_begin(*trie);
+			for (; !trie_it_finished(it); trie_it_next(it)) {
 				size_t len = 0;
-				const char *data = hattrie_iter_key(it, &len);
-				*hattrie_get(extra->current_trie, data, len) = NULL;
+				const char *data = trie_it_key(it, &len);
+				*trie_get_ins(extra->current_trie, data, len) = NULL;
 			}
-			hattrie_iter_free(it);
+			trie_it_free(it);
 		} else {
-			*hattrie_get(extra->current_trie, value, strlen(value)) = NULL;
+			*trie_get_ins(extra->current_trie, value, strlen(value)) = NULL;
 		}
 	}
 
@@ -250,10 +250,10 @@ static void acl_next(void *scanner, const char *value)
 
 	if (trie != NULL) {
 		bool init = true;
-		hattrie_iter_t *it = hattrie_iter_begin(*trie);
-		for (; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
+		trie_it_t *it = trie_it_begin(*trie);
+		for (; !trie_it_finished(it); trie_it_next(it)) {
 			size_t len = 0;
-			const char *data = hattrie_iter_key(it, &len);
+			const char *data = trie_it_key(it, &len);
 			if (init) {
 				init = false;
 			} else {
@@ -262,7 +262,7 @@ static void acl_next(void *scanner, const char *value)
 			f_val(scanner, extra->run, false, "%s", _str);
 			f_val(scanner, extra->run, false, "%.*s", (int)len, data);
 		}
-		hattrie_iter_free(it);
+		trie_it_free(it);
 	} else {
 		f_val(scanner, extra->run, false, "%s", _str);
 		f_val(scanner, extra->run, false, "%s", value);
@@ -280,17 +280,17 @@ static void acl_end(void *scanner)
 static bool is_acl(void *scanner, const char *str) {
 	conf_extra_t *extra = cf_get_extra(scanner);
 
-	return hattrie_tryget(extra->share->acl_xfer, str, strlen(str))    != NULL ||
-	       hattrie_tryget(extra->share->acl_notify, str, strlen(str))  != NULL ||
-	       hattrie_tryget(extra->share->acl_update, str, strlen(str))  != NULL;
+	return trie_get_try(extra->share->acl_xfer, str, strlen(str))    != NULL ||
+	       trie_get_try(extra->share->acl_notify, str, strlen(str))  != NULL ||
+	       trie_get_try(extra->share->acl_update, str, strlen(str))  != NULL;
 }
 
 static bool have_acl(void *scanner) {
 	conf_extra_t *extra = cf_get_extra(scanner);
 
-	return (hattrie_weight(extra->share->acl_xfer) +
-	        hattrie_weight(extra->share->acl_notify) +
-	        hattrie_weight(extra->share->acl_update)) > 0;
+	return (trie_weight(extra->share->acl_xfer) +
+	        trie_weight(extra->share->acl_notify) +
+	        trie_weight(extra->share->acl_update)) > 0;
 }
 
 static char *acl_actions(void *scanner, const char *str) {
@@ -301,15 +301,15 @@ static char *acl_actions(void *scanner, const char *str) {
 
 	strlcpy(actions, "[", sizeof(actions));
 
-	if (hattrie_tryget(extra->share->acl_xfer, str, strlen(str)) != NULL) {
+	if (trie_get_try(extra->share->acl_xfer, str, strlen(str)) != NULL) {
 		strlcat(actions, _first ? "" : ", ", sizeof(actions)); _first = false;
 		strlcat(actions, "transfer", sizeof(actions));
 	}
-	if (hattrie_tryget(extra->share->acl_notify, str, strlen(str)) != NULL) {
+	if (trie_get_try(extra->share->acl_notify, str, strlen(str)) != NULL) {
 		strlcat(actions, _first ? "" : ", ", sizeof(actions)); _first = false;
 		strlcat(actions, "notify", sizeof(actions));
 	}
-	if (hattrie_tryget(extra->share->acl_update, str, strlen(str)) != NULL) {
+	if (trie_get_try(extra->share->acl_update, str, strlen(str)) != NULL) {
 		strlcat(actions, _first ? "" : ", ", sizeof(actions)); _first = false;
 		strlcat(actions, "update", sizeof(actions));
 	}
@@ -324,10 +324,10 @@ static void grp_init(void *scanner, const char *name)
 	conf_extra_t *extra = cf_get_extra(scanner);
 
 	if (extra->run == S_FIRST) {
-		hattrie_t **trie = (hattrie_t **)hattrie_get(extra->share->groups,
+		trie_t **trie = (trie_t **)trie_get_ins(extra->share->groups,
 		                                             name, strlen(name));
 		if (*trie == NULL) {
-			*trie = hattrie_create(NULL);
+			*trie = trie_create(NULL);
 		}
 		extra->current_trie = *trie;
 	}
@@ -338,7 +338,7 @@ static void grp_add(void *scanner, const char *value)
 	conf_extra_t *extra = cf_get_extra(scanner);
 
 	if (extra->run == S_FIRST) {
-		*hattrie_get(extra->current_trie, value, strlen(value)) = NULL;
+		*trie_get_ins(extra->current_trie, value, strlen(value)) = NULL;
 	}
 }
 
diff --git a/src/utils/knot1to2/extra.h b/src/utils/knot1to2/extra.h
index c38de7acde0ab5cdba6674ceb7cc78fa92f0bf1b..58c9e256a146e63b9deac45eb137eef58b8da93f 100644
--- a/src/utils/knot1to2/extra.h
+++ b/src/utils/knot1to2/extra.h
@@ -20,18 +20,18 @@
 
 #include "utils/knot1to2/includes.h"
 #include "utils/knot1to2/scheme.h"
-#include "contrib/hat-trie/hat-trie.h"
+#include "contrib/qp-trie/trie.h"
 
 typedef struct {
 	FILE *out;
 	bool have_sections[S_LAST - S_FIRST + 1];
-	hattrie_t *ifaces;
-	hattrie_t *groups;
-	hattrie_t *remotes;
-	hattrie_t *acl_xfer;
-	hattrie_t *acl_notify;
-	hattrie_t *acl_update;
-	hattrie_t *acl_control;
+	trie_t *ifaces;
+	trie_t *groups;
+	trie_t *remotes;
+	trie_t *acl_xfer;
+	trie_t *acl_notify;
+	trie_t *acl_update;
+	trie_t *acl_control;
 } share_t;
 
 /*!
@@ -42,7 +42,7 @@ typedef struct {
 	conf_includes_t *includes; // Used to handle filenames in includes.
 	int run;                   // Current run number.
 	share_t *share;            // Variables shared among all runs.
-	hattrie_t *current_trie;
+	trie_t *current_trie;
 	const char *current_key;
 } conf_extra_t;
 
diff --git a/src/utils/knot1to2/main.c b/src/utils/knot1to2/main.c
index e01540814e1b5173bd544c463ad79bc4646a6854..1c2ac790c16a335f3707e4a5320dc2f7e7546225 100644
--- a/src/utils/knot1to2/main.c
+++ b/src/utils/knot1to2/main.c
@@ -23,7 +23,7 @@
 #include "utils/common/params.h"
 #include "utils/knot1to2/extra.h"
 #include "utils/knot1to2/scheme.h"
-#include "contrib/hat-trie/hat-trie.h"
+#include "contrib/qp-trie/trie.h"
 #include "contrib/string.h"
 
 #define PROGRAM_NAME "knot1to2"
@@ -75,12 +75,12 @@ static int convert(const char *file_out, const char *file_in)
 
 	share_t share = {
 		.out = out,
-		.ifaces = hattrie_create(NULL),
-		.groups = hattrie_create(NULL),
-		.remotes = hattrie_create(NULL),
-		.acl_xfer = hattrie_create(NULL),
-		.acl_notify = hattrie_create(NULL),
-		.acl_update = hattrie_create(NULL)
+		.ifaces = trie_create(NULL),
+		.groups = trie_create(NULL),
+		.remotes = trie_create(NULL),
+		.acl_xfer = trie_create(NULL),
+		.acl_notify = trie_create(NULL),
+		.acl_update = trie_create(NULL)
 	};
 
 	// Parse the input file multiple times to get some context.
@@ -93,28 +93,28 @@ static int convert(const char *file_out, const char *file_in)
 	}
 
 	// Remove ifaces data.
-	hattrie_iter_t *it = hattrie_iter_begin(share.ifaces);
-	for (; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
-		char *data = *hattrie_iter_val(it);
+	trie_it_t *it = trie_it_begin(share.ifaces);
+	for (; !trie_it_finished(it); trie_it_next(it)) {
+		char *data = *trie_it_val(it);
 		free(data);
 	}
-	hattrie_iter_free(it);
+	trie_it_free(it);
 
 	// Remove groups data.
-	it = hattrie_iter_begin(share.groups);
-	for (; !hattrie_iter_finished(it); hattrie_iter_next(it)) {
-		hattrie_t *trie = *hattrie_iter_val(it);
-		hattrie_free(trie);
+	it = trie_it_begin(share.groups);
+	for (; !trie_it_finished(it); trie_it_next(it)) {
+		trie_t *trie = *trie_it_val(it);
+		trie_free(trie);
 	}
-	hattrie_iter_free(it);
+	trie_it_free(it);
 
 	// Remove empty tries without data.
-	hattrie_free(share.ifaces);
-	hattrie_free(share.groups);
-	hattrie_free(share.remotes);
-	hattrie_free(share.acl_xfer);
-	hattrie_free(share.acl_notify);
-	hattrie_free(share.acl_update);
+	trie_free(share.ifaces);
+	trie_free(share.groups);
+	trie_free(share.remotes);
+	trie_free(share.acl_xfer);
+	trie_free(share.acl_notify);
+	trie_free(share.acl_update);
 
 	fclose(out);
 
diff --git a/src/utils/knotc/commands.c b/src/utils/knotc/commands.c
index afcd8fe1e48783e37c2dfb960d434ab1dbcddc86..c88ed73facad7fe3c129217b925c21e07a376621 100644
--- a/src/utils/knotc/commands.c
+++ b/src/utils/knotc/commands.c
@@ -571,7 +571,7 @@ static int zone_memstats(const knot_dname_t *dname, void *data)
 
 	// Init memory estimation context.
 	zone_estim_t est = {
-		.node_table = hattrie_create(&mem_ctx),
+		.node_table = trie_create(&mem_ctx),
 	};
 
 	char buff[KNOT_DNAME_TXT_MAXLEN + 1];
@@ -582,7 +582,7 @@ static int zone_memstats(const knot_dname_t *dname, void *data)
 	if (est.node_table == NULL || zone_name == NULL || zone_file == NULL ||
 	    zs == NULL) {
 		log_zone_error(dname, "%s", knot_strerror(KNOT_ENOMEM));
-		hattrie_free(est.node_table);
+		trie_free(est.node_table);
 		free(zone_file);
 		free(zs);
 		return KNOT_ENOMEM;
@@ -595,8 +595,8 @@ static int zone_memstats(const knot_dname_t *dname, void *data)
 	    zs_parse_all(zs) != 0) {
 		log_zone_error(dname, "failed to parse zone file '%s' (%s)",
 		               zone_file, zs_errorname(zs->error.code));
-		hattrie_apply_rev(est.node_table, estimator_free_trie_node, NULL);
-		hattrie_free(est.node_table);
+		trie_apply(est.node_table, estimator_free_trie_node, NULL);
+		trie_free(est.node_table);
 		free(zone_file);
 		zs_deinit(zs);
 		free(zs);
@@ -607,8 +607,8 @@ static int zone_memstats(const knot_dname_t *dname, void *data)
 	free(zs);
 
 	// Cleanup.
-	hattrie_apply_rev(est.node_table, estimator_free_trie_node, NULL);
-	hattrie_free(est.node_table);
+	trie_apply(est.node_table, estimator_free_trie_node, NULL);
+	trie_free(est.node_table);
 
 	double zone_size = (est.rdata_size + est.node_size + est.dname_size +
 	                    malloc_size) / (1024.0 * 1024.0);
diff --git a/src/utils/knotc/estimator.c b/src/utils/knotc/estimator.c
index 574c99eb74a2a50a707d6ffa06bba0e81bd9833d..76ba935cf07a98f7e7c9465449463b2628a55ea1 100644
--- a/src/utils/knotc/estimator.c
+++ b/src/utils/knotc/estimator.c
@@ -66,7 +66,7 @@ static int dummy_node_add_type(list_t *l, uint16_t t)
 }
 
 // return: 0 - unique, 1 - duplicate
-static int insert_dname_into_table(hattrie_t *table, const knot_dname_t *d,
+static int insert_dname_into_table(trie_t *table, const knot_dname_t *d,
                                    list_t **dummy_node)
 {
 	int d_size = knot_dname_size(d);
@@ -74,13 +74,13 @@ static int insert_dname_into_table(hattrie_t *table, const knot_dname_t *d,
 		return KNOT_EINVAL;
 	}
 
-	value_t *val = hattrie_tryget(table, (char *)d, d_size);
+	trie_val_t *val = trie_get_try(table, (char *)d, d_size);
 	if (val == NULL) {
 		// Create new dummy node to use for this dname
 		*dummy_node = malloc(sizeof(list_t));
 		assert(dummy_node != NULL);
 		init_list(*dummy_node);
-		*hattrie_get(table, (char *)d, d_size) = *dummy_node;
+		*trie_get_ins(table, (char *)d, d_size) = *dummy_node;
 		return 0;
 	} else {
 		// Return previously found dummy node
@@ -139,7 +139,7 @@ void estimator_rrset_memsize_wrap(zs_scanner_t *scanner)
 	rrset_memsize(scanner->process.data, scanner);
 }
 
-int estimator_free_trie_node(value_t *val, void *data)
+int estimator_free_trie_node(trie_val_t *val, void *data)
 {
 	UNUSED(data);
 	list_t *trie_n = (list_t *)(*val);
diff --git a/src/utils/knotc/estimator.h b/src/utils/knotc/estimator.h
index af9ae648ba1642bbc7cb3aff9c6056a6feae5af0..086f29950d6a68ae81d5c70a4ed989180209fef0 100644
--- a/src/utils/knotc/estimator.h
+++ b/src/utils/knotc/estimator.h
@@ -24,18 +24,18 @@
 
 #pragma once
 
-#include "contrib/hat-trie/hat-trie.h"
+#include "contrib/qp-trie/trie.h"
 #include "zscanner/scanner.h"
 
 /*!
  * \brief Memory estimation context.
  */
 typedef struct {
-	hattrie_t *node_table; /*!< Same trie is in actual zone. */
-	size_t rdata_size;     /*!< Estimated RDATA size. */
-	size_t dname_size;     /*!< Estimated DNAME size. */
-	size_t node_size;      /*!< Estimated node size. */
-	size_t record_count;   /*!< Total record count for zone. */
+	trie_t *node_table;  /*!< Same trie is in actual zone. */
+	size_t rdata_size;   /*!< Estimated RDATA size. */
+	size_t dname_size;   /*!< Estimated DNAME size. */
+	size_t node_size;    /*!< Estimated node size. */
+	size_t record_count; /*!< Total record count for zone. */
 } zone_estim_t;
 
 /*!
@@ -64,10 +64,10 @@ void estimator_free(void *p);
 void estimator_rrset_memsize_wrap(zs_scanner_t *scanner);
 
 /*!
- * \brief Cleanup function for use with hattrie.
+ * \brief Cleanup function for use with trie.
  *
  * \param p Data to free.
  */
-int estimator_free_trie_node(value_t *val, void *data);
+int estimator_free_trie_node(trie_val_t *val, void *data);
 
 /*! @} */
diff --git a/tests/contrib/test_qp-trie.c b/tests/contrib/test_qp-trie.c
index e1a04c79d7dede24aae385b9bc8aad9b589c9a6c..f1440f2263af0916c2dd6fcc3f60b4044b7ddb81 100644
--- a/tests/contrib/test_qp-trie.c
+++ b/tests/contrib/test_qp-trie.c
@@ -19,7 +19,7 @@
 #include <time.h>
 #include <tap/basic.h>
 
-#include "contrib/qp-trie/qp.h"
+#include "contrib/qp-trie/trie.h"
 #include "contrib/macros.h"
 #include "contrib/string.h"
 #include "libknot/errcode.h"