// SPDX-License-Identifier: GPL-2.0

#include "bcachefs.h"
#include "bkey_buf.h"
#include "btree_locking.h"
#include "btree_update.h"
#include "btree_update_interior.h"
#include "btree_write_buffer.h"
#include "error.h"
#include "extents.h"
#include "journal.h"
#include "journal_io.h"
#include "journal_reclaim.h"

#include <linux/prefetch.h>
#include <linux/sort.h>

static int bch2_btree_write_buffer_journal_flush(struct journal *,
				struct journal_entry_pin *, u64);

static int bch2_journal_keys_to_write_buffer(struct bch_fs *, struct journal_buf *);

static inline bool __wb_key_ref_cmp(const struct wb_key_ref *l, const struct wb_key_ref *r)
{
	return (cmp_int(l->hi, r->hi) ?:
		cmp_int(l->mi, r->mi) ?:
		cmp_int(l->lo, r->lo)) >= 0;
}

static inline bool wb_key_ref_cmp(const struct wb_key_ref *l, const struct wb_key_ref *r)
{
#ifdef CONFIG_X86_64
	int cmp;

	asm("mov   (%[l]), %%rax;"
	    "sub   (%[r]), %%rax;"
	    "mov  8(%[l]), %%rax;"
	    "sbb  8(%[r]), %%rax;"
	    "mov 16(%[l]), %%rax;"
	    "sbb 16(%[r]), %%rax;"
	    : "=@ccae" (cmp)
	    : [l] "r" (l), [r] "r" (r)
	    : "rax", "cc");

	EBUG_ON(cmp != __wb_key_ref_cmp(l, r));
	return cmp;
#else
	return __wb_key_ref_cmp(l, r);
#endif
}

static int wb_key_seq_cmp(const void *_l, const void *_r)
{
	const struct btree_write_buffered_key *l = _l;
	const struct btree_write_buffered_key *r = _r;

	return cmp_int(l->journal_seq, r->journal_seq);
}

/* Compare excluding idx, the low 24 bits: */
static inline bool wb_key_eq(const void *_l, const void *_r)
{
	const struct wb_key_ref *l = _l;
	const struct wb_key_ref *r = _r;

	return !((l->hi ^ r->hi)|
		 (l->mi ^ r->mi)|
		 ((l->lo >> 24) ^ (r->lo >> 24)));
}

static noinline void wb_sort(struct wb_key_ref *base, size_t num)
{
	size_t n = num, a = num / 2;

	if (!a)		/* num < 2 || size == 0 */
		return;

	for (;;) {
		size_t b, c, d;

		if (a)			/* Building heap: sift down --a */
			--a;
		else if (--n)		/* Sorting: Extract root to --n */
			swap(base[0], base[n]);
		else			/* Sort complete */
			break;

		/*
		 * Sift element at "a" down into heap.  This is the
		 * "bottom-up" variant, which significantly reduces
		 * calls to cmp_func(): we find the sift-down path all
		 * the way to the leaves (one compare per level), then
		 * backtrack to find where to insert the target element.
		 *
		 * Because elements tend to sift down close to the leaves,
		 * this uses fewer compares than doing two per level
		 * on the way down.  (A bit more than half as many on
		 * average, 3/4 worst-case.)
		 */
		for (b = a; c = 2*b + 1, (d = c + 1) < n;)
			b = wb_key_ref_cmp(base + c, base + d) ? c : d;
		if (d == n)		/* Special case last leaf with no sibling */
			b = c;

		/* Now backtrack from "b" to the correct location for "a" */
		while (b != a && wb_key_ref_cmp(base + a, base + b))
			b = (b - 1) / 2;
		c = b;			/* Where "a" belongs */
		while (b != a) {	/* Shift it into place */
			b = (b - 1) / 2;
			swap(base[b], base[c]);
		}
	}
}

static noinline int wb_flush_one_slowpath(struct btree_trans *trans,
					  struct btree_iter *iter,
					  struct btree_write_buffered_key *wb)
{
	struct btree_path *path = btree_iter_path(trans, iter);

	bch2_btree_node_unlock_write(trans, path, path->l[0].b);

	trans->journal_res.seq = wb->journal_seq;

	return bch2_trans_update(trans, iter, &wb->k,
				 BTREE_UPDATE_internal_snapshot_node) ?:
		bch2_trans_commit(trans, NULL, NULL,
				  BCH_TRANS_COMMIT_no_enospc|
				  BCH_TRANS_COMMIT_no_check_rw|
				  BCH_TRANS_COMMIT_no_journal_res|
				  BCH_TRANS_COMMIT_journal_reclaim);
}

static inline int wb_flush_one(struct btree_trans *trans, struct btree_iter *iter,
			       struct btree_write_buffered_key *wb,
			       bool *write_locked, size_t *fast)
{
	struct btree_path *path;
	int ret;

	EBUG_ON(!wb->journal_seq);
	EBUG_ON(!trans->c->btree_write_buffer.flushing.pin.seq);
	EBUG_ON(trans->c->btree_write_buffer.flushing.pin.seq > wb->journal_seq);

	ret = bch2_btree_iter_traverse(iter);
	if (ret)
		return ret;

	/*
	 * We can't clone a path that has write locks: unshare it now, before
	 * set_pos and traverse():
	 */
	if (btree_iter_path(trans, iter)->ref > 1)
		iter->path = __bch2_btree_path_make_mut(trans, iter->path, true, _THIS_IP_);

	path = btree_iter_path(trans, iter);

	if (!*write_locked) {
		ret = bch2_btree_node_lock_write(trans, path, &path->l[0].b->c);
		if (ret)
			return ret;

		bch2_btree_node_prep_for_write(trans, path, path->l[0].b);
		*write_locked = true;
	}

	if (unlikely(!bch2_btree_node_insert_fits(path->l[0].b, wb->k.k.u64s))) {
		*write_locked = false;
		return wb_flush_one_slowpath(trans, iter, wb);
	}

	bch2_btree_insert_key_leaf(trans, path, &wb->k, wb->journal_seq);
	(*fast)++;
	return 0;
}

/*
 * Update a btree with a write buffered key using the journal seq of the
 * original write buffer insert.
 *
 * It is not safe to rejournal the key once it has been inserted into the write
 * buffer because that may break recovery ordering. For example, the key may
 * have already been modified in the active write buffer in a seq that comes
 * before the current transaction. If we were to journal this key again and
 * crash, recovery would process updates in the wrong order.
 */
static int
btree_write_buffered_insert(struct btree_trans *trans,
			  struct btree_write_buffered_key *wb)
{
	struct btree_iter iter;
	int ret;

	bch2_trans_iter_init(trans, &iter, wb->btree, bkey_start_pos(&wb->k.k),
			     BTREE_ITER_cached|BTREE_ITER_intent);

	trans->journal_res.seq = wb->journal_seq;

	ret   = bch2_btree_iter_traverse(&iter) ?:
		bch2_trans_update(trans, &iter, &wb->k,
				  BTREE_UPDATE_internal_snapshot_node);
	bch2_trans_iter_exit(trans, &iter);
	return ret;
}

static void move_keys_from_inc_to_flushing(struct btree_write_buffer *wb)
{
	struct bch_fs *c = container_of(wb, struct bch_fs, btree_write_buffer);
	struct journal *j = &c->journal;

	if (!wb->inc.keys.nr)
		return;

	bch2_journal_pin_add(j, wb->inc.keys.data[0].journal_seq, &wb->flushing.pin,
			     bch2_btree_write_buffer_journal_flush);

	darray_resize(&wb->flushing.keys, min_t(size_t, 1U << 20, wb->flushing.keys.nr + wb->inc.keys.nr));
	darray_resize(&wb->sorted, wb->flushing.keys.size);

	if (!wb->flushing.keys.nr && wb->sorted.size >= wb->inc.keys.nr) {
		swap(wb->flushing.keys, wb->inc.keys);
		goto out;
	}

	size_t nr = min(darray_room(wb->flushing.keys),
			wb->sorted.size - wb->flushing.keys.nr);
	nr = min(nr, wb->inc.keys.nr);

	memcpy(&darray_top(wb->flushing.keys),
	       wb->inc.keys.data,
	       sizeof(wb->inc.keys.data[0]) * nr);

	memmove(wb->inc.keys.data,
		wb->inc.keys.data + nr,
	       sizeof(wb->inc.keys.data[0]) * (wb->inc.keys.nr - nr));

	wb->flushing.keys.nr	+= nr;
	wb->inc.keys.nr		-= nr;
out:
	if (!wb->inc.keys.nr)
		bch2_journal_pin_drop(j, &wb->inc.pin);
	else
		bch2_journal_pin_update(j, wb->inc.keys.data[0].journal_seq, &wb->inc.pin,
					bch2_btree_write_buffer_journal_flush);

	if (j->watermark) {
		spin_lock(&j->lock);
		bch2_journal_set_watermark(j);
		spin_unlock(&j->lock);
	}

	BUG_ON(wb->sorted.size < wb->flushing.keys.nr);
}

static int bch2_btree_write_buffer_flush_locked(struct btree_trans *trans)
{
	struct bch_fs *c = trans->c;
	struct journal *j = &c->journal;
	struct btree_write_buffer *wb = &c->btree_write_buffer;
	struct btree_iter iter = { NULL };
	size_t skipped = 0, fast = 0, slowpath = 0;
	bool write_locked = false;
	int ret = 0;

	bch2_trans_unlock(trans);
	bch2_trans_begin(trans);

	mutex_lock(&wb->inc.lock);
	move_keys_from_inc_to_flushing(wb);
	mutex_unlock(&wb->inc.lock);

	for (size_t i = 0; i < wb->flushing.keys.nr; i++) {
		wb->sorted.data[i].idx = i;
		wb->sorted.data[i].btree = wb->flushing.keys.data[i].btree;
		memcpy(&wb->sorted.data[i].pos, &wb->flushing.keys.data[i].k.k.p, sizeof(struct bpos));
	}
	wb->sorted.nr = wb->flushing.keys.nr;

	/*
	 * We first sort so that we can detect and skip redundant updates, and
	 * then we attempt to flush in sorted btree order, as this is most
	 * efficient.
	 *
	 * However, since we're not flushing in the order they appear in the
	 * journal we won't be able to drop our journal pin until everything is
	 * flushed - which means this could deadlock the journal if we weren't
	 * passing BCH_TRANS_COMMIT_journal_reclaim. This causes the update to fail
	 * if it would block taking a journal reservation.
	 *
	 * If that happens, simply skip the key so we can optimistically insert
	 * as many keys as possible in the fast path.
	 */
	wb_sort(wb->sorted.data, wb->sorted.nr);

	darray_for_each(wb->sorted, i) {
		struct btree_write_buffered_key *k = &wb->flushing.keys.data[i->idx];

		for (struct wb_key_ref *n = i + 1; n < min(i + 4, &darray_top(wb->sorted)); n++)
			prefetch(&wb->flushing.keys.data[n->idx]);

		BUG_ON(!k->journal_seq);

		if (i + 1 < &darray_top(wb->sorted) &&
		    wb_key_eq(i, i + 1)) {
			struct btree_write_buffered_key *n = &wb->flushing.keys.data[i[1].idx];

			skipped++;
			n->journal_seq = min_t(u64, n->journal_seq, k->journal_seq);
			k->journal_seq = 0;
			continue;
		}

		if (write_locked) {
			struct btree_path *path = btree_iter_path(trans, &iter);

			if (path->btree_id != i->btree ||
			    bpos_gt(k->k.k.p, path->l[0].b->key.k.p)) {
				bch2_btree_node_unlock_write(trans, path, path->l[0].b);
				write_locked = false;

				ret = lockrestart_do(trans,
					bch2_btree_iter_traverse(&iter) ?:
					bch2_foreground_maybe_merge(trans, iter.path, 0,
							BCH_WATERMARK_reclaim|
							BCH_TRANS_COMMIT_journal_reclaim|
							BCH_TRANS_COMMIT_no_check_rw|
							BCH_TRANS_COMMIT_no_enospc));
				if (ret)
					goto err;
			}
		}

		if (!iter.path || iter.btree_id != k->btree) {
			bch2_trans_iter_exit(trans, &iter);
			bch2_trans_iter_init(trans, &iter, k->btree, k->k.k.p,
					     BTREE_ITER_intent|BTREE_ITER_all_snapshots);
		}

		bch2_btree_iter_set_pos(&iter, k->k.k.p);
		btree_iter_path(trans, &iter)->preserve = false;

		do {
			if (race_fault()) {
				ret = -BCH_ERR_journal_reclaim_would_deadlock;
				break;
			}

			ret = wb_flush_one(trans, &iter, k, &write_locked, &fast);
			if (!write_locked)
				bch2_trans_begin(trans);
		} while (bch2_err_matches(ret, BCH_ERR_transaction_restart));

		if (!ret) {
			k->journal_seq = 0;
		} else if (ret == -BCH_ERR_journal_reclaim_would_deadlock) {
			slowpath++;
			ret = 0;
		} else
			break;
	}

	if (write_locked) {
		struct btree_path *path = btree_iter_path(trans, &iter);
		bch2_btree_node_unlock_write(trans, path, path->l[0].b);
	}
	bch2_trans_iter_exit(trans, &iter);

	if (ret)
		goto err;

	if (slowpath) {
		/*
		 * Flush in the order they were present in the journal, so that
		 * we can release journal pins:
		 * The fastpath zapped the seq of keys that were successfully flushed so
		 * we can skip those here.
		 */
		trace_and_count(c, write_buffer_flush_slowpath, trans, slowpath, wb->flushing.keys.nr);

		sort(wb->flushing.keys.data,
		     wb->flushing.keys.nr,
		     sizeof(wb->flushing.keys.data[0]),
		     wb_key_seq_cmp, NULL);

		darray_for_each(wb->flushing.keys, i) {
			if (!i->journal_seq)
				continue;

			bch2_journal_pin_update(j, i->journal_seq, &wb->flushing.pin,
						bch2_btree_write_buffer_journal_flush);

			bch2_trans_begin(trans);

			ret = commit_do(trans, NULL, NULL,
					BCH_WATERMARK_reclaim|
					BCH_TRANS_COMMIT_journal_reclaim|
					BCH_TRANS_COMMIT_no_check_rw|
					BCH_TRANS_COMMIT_no_enospc|
					BCH_TRANS_COMMIT_no_journal_res ,
					btree_write_buffered_insert(trans, i));
			if (ret)
				goto err;
		}
	}
err:
	bch2_fs_fatal_err_on(ret, c, "%s", bch2_err_str(ret));
	trace_write_buffer_flush(trans, wb->flushing.keys.nr, skipped, fast, 0);
	bch2_journal_pin_drop(j, &wb->flushing.pin);
	wb->flushing.keys.nr = 0;
	return ret;
}

static int fetch_wb_keys_from_journal(struct bch_fs *c, u64 seq)
{
	struct journal *j = &c->journal;
	struct journal_buf *buf;
	int ret = 0;

	while (!ret && (buf = bch2_next_write_buffer_flush_journal_buf(j, seq))) {
		ret = bch2_journal_keys_to_write_buffer(c, buf);
		mutex_unlock(&j->buf_lock);
	}

	return ret;
}

static int btree_write_buffer_flush_seq(struct btree_trans *trans, u64 seq)
{
	struct bch_fs *c = trans->c;
	struct btree_write_buffer *wb = &c->btree_write_buffer;
	int ret = 0, fetch_from_journal_err;

	do {
		bch2_trans_unlock(trans);

		fetch_from_journal_err = fetch_wb_keys_from_journal(c, seq);

		/*
		 * On memory allocation failure, bch2_btree_write_buffer_flush_locked()
		 * is not guaranteed to empty wb->inc:
		 */
		mutex_lock(&wb->flushing.lock);
		ret = bch2_btree_write_buffer_flush_locked(trans);
		mutex_unlock(&wb->flushing.lock);
	} while (!ret &&
		 (fetch_from_journal_err ||
		  (wb->inc.pin.seq && wb->inc.pin.seq <= seq) ||
		  (wb->flushing.pin.seq && wb->flushing.pin.seq <= seq)));

	return ret;
}

static int bch2_btree_write_buffer_journal_flush(struct journal *j,
				struct journal_entry_pin *_pin, u64 seq)
{
	struct bch_fs *c = container_of(j, struct bch_fs, journal);

	return bch2_trans_run(c, btree_write_buffer_flush_seq(trans, seq));
}

int bch2_btree_write_buffer_flush_sync(struct btree_trans *trans)
{
	struct bch_fs *c = trans->c;

	trace_and_count(c, write_buffer_flush_sync, trans, _RET_IP_);

	return btree_write_buffer_flush_seq(trans, journal_cur_seq(&c->journal));
}

int bch2_btree_write_buffer_flush_nocheck_rw(struct btree_trans *trans)
{
	struct bch_fs *c = trans->c;
	struct btree_write_buffer *wb = &c->btree_write_buffer;
	int ret = 0;

	if (mutex_trylock(&wb->flushing.lock)) {
		ret = bch2_btree_write_buffer_flush_locked(trans);
		mutex_unlock(&wb->flushing.lock);
	}

	return ret;
}

int bch2_btree_write_buffer_tryflush(struct btree_trans *trans)
{
	struct bch_fs *c = trans->c;

	if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_btree_write_buffer))
		return -BCH_ERR_erofs_no_writes;

	int ret = bch2_btree_write_buffer_flush_nocheck_rw(trans);
	bch2_write_ref_put(c, BCH_WRITE_REF_btree_write_buffer);
	return ret;
}

/**
 * In check and repair code, when checking references to write buffer btrees we
 * need to issue a flush before we have a definitive error: this issues a flush
 * if this is a key we haven't yet checked.
 */
int bch2_btree_write_buffer_maybe_flush(struct btree_trans *trans,
					struct bkey_s_c referring_k,
					struct bkey_buf *last_flushed)
{
	struct bch_fs *c = trans->c;
	struct bkey_buf tmp;
	int ret = 0;

	bch2_bkey_buf_init(&tmp);

	if (!bkey_and_val_eq(referring_k, bkey_i_to_s_c(last_flushed->k))) {
		bch2_bkey_buf_reassemble(&tmp, c, referring_k);

		if (bkey_is_btree_ptr(referring_k.k)) {
			bch2_trans_unlock(trans);
			bch2_btree_interior_updates_flush(c);
		}

		ret = bch2_btree_write_buffer_flush_sync(trans);
		if (ret)
			goto err;

		bch2_bkey_buf_copy(last_flushed, c, tmp.k);
		ret = -BCH_ERR_transaction_restart_write_buffer_flush;
	}
err:
	bch2_bkey_buf_exit(&tmp, c);
	return ret;
}

static void bch2_btree_write_buffer_flush_work(struct work_struct *work)
{
	struct bch_fs *c = container_of(work, struct bch_fs, btree_write_buffer.flush_work);
	struct btree_write_buffer *wb = &c->btree_write_buffer;
	int ret;

	mutex_lock(&wb->flushing.lock);
	do {
		ret = bch2_trans_run(c, bch2_btree_write_buffer_flush_locked(trans));
	} while (!ret && bch2_btree_write_buffer_should_flush(c));
	mutex_unlock(&wb->flushing.lock);

	bch2_write_ref_put(c, BCH_WRITE_REF_btree_write_buffer);
}

int bch2_journal_key_to_wb_slowpath(struct bch_fs *c,
			     struct journal_keys_to_wb *dst,
			     enum btree_id btree, struct bkey_i *k)
{
	struct btree_write_buffer *wb = &c->btree_write_buffer;
	int ret;
retry:
	ret = darray_make_room_gfp(&dst->wb->keys, 1, GFP_KERNEL);
	if (!ret && dst->wb == &wb->flushing)
		ret = darray_resize(&wb->sorted, wb->flushing.keys.size);

	if (unlikely(ret)) {
		if (dst->wb == &c->btree_write_buffer.flushing) {
			mutex_unlock(&dst->wb->lock);
			dst->wb = &c->btree_write_buffer.inc;
			bch2_journal_pin_add(&c->journal, dst->seq, &dst->wb->pin,
					     bch2_btree_write_buffer_journal_flush);
			goto retry;
		}

		return ret;
	}

	dst->room = darray_room(dst->wb->keys);
	if (dst->wb == &wb->flushing)
		dst->room = min(dst->room, wb->sorted.size - wb->flushing.keys.nr);
	BUG_ON(!dst->room);
	BUG_ON(!dst->seq);

	struct btree_write_buffered_key *wb_k = &darray_top(dst->wb->keys);
	wb_k->journal_seq	= dst->seq;
	wb_k->btree		= btree;
	bkey_copy(&wb_k->k, k);
	dst->wb->keys.nr++;
	dst->room--;
	return 0;
}

void bch2_journal_keys_to_write_buffer_start(struct bch_fs *c, struct journal_keys_to_wb *dst, u64 seq)
{
	struct btree_write_buffer *wb = &c->btree_write_buffer;

	if (mutex_trylock(&wb->flushing.lock)) {
		mutex_lock(&wb->inc.lock);
		move_keys_from_inc_to_flushing(wb);

		/*
		 * Attempt to skip wb->inc, and add keys directly to
		 * wb->flushing, saving us a copy later:
		 */

		if (!wb->inc.keys.nr) {
			dst->wb = &wb->flushing;
		} else {
			mutex_unlock(&wb->flushing.lock);
			dst->wb = &wb->inc;
		}
	} else {
		mutex_lock(&wb->inc.lock);
		dst->wb = &wb->inc;
	}

	dst->room = darray_room(dst->wb->keys);
	if (dst->wb == &wb->flushing)
		dst->room = min(dst->room, wb->sorted.size - wb->flushing.keys.nr);
	dst->seq = seq;

	bch2_journal_pin_add(&c->journal, seq, &dst->wb->pin,
			     bch2_btree_write_buffer_journal_flush);
}

void bch2_journal_keys_to_write_buffer_end(struct bch_fs *c, struct journal_keys_to_wb *dst)
{
	struct btree_write_buffer *wb = &c->btree_write_buffer;

	if (!dst->wb->keys.nr)
		bch2_journal_pin_drop(&c->journal, &dst->wb->pin);

	if (bch2_btree_write_buffer_should_flush(c) &&
	    __bch2_write_ref_tryget(c, BCH_WRITE_REF_btree_write_buffer) &&
	    !queue_work(system_unbound_wq, &c->btree_write_buffer.flush_work))
		bch2_write_ref_put(c, BCH_WRITE_REF_btree_write_buffer);

	if (dst->wb == &wb->flushing)
		mutex_unlock(&wb->flushing.lock);
	mutex_unlock(&wb->inc.lock);
}

static int bch2_journal_keys_to_write_buffer(struct bch_fs *c, struct journal_buf *buf)
{
	struct journal_keys_to_wb dst;
	int ret = 0;

	bch2_journal_keys_to_write_buffer_start(c, &dst, le64_to_cpu(buf->data->seq));

	for_each_jset_entry_type(entry, buf->data, BCH_JSET_ENTRY_write_buffer_keys) {
		jset_entry_for_each_key(entry, k) {
			ret = bch2_journal_key_to_wb(c, &dst, entry->btree_id, k);
			if (ret)
				goto out;
		}

		entry->type = BCH_JSET_ENTRY_btree_keys;
	}

	spin_lock(&c->journal.lock);
	buf->need_flush_to_write_buffer = false;
	spin_unlock(&c->journal.lock);
out:
	bch2_journal_keys_to_write_buffer_end(c, &dst);
	return ret;
}

static int wb_keys_resize(struct btree_write_buffer_keys *wb, size_t new_size)
{
	if (wb->keys.size >= new_size)
		return 0;

	if (!mutex_trylock(&wb->lock))
		return -EINTR;

	int ret = darray_resize(&wb->keys, new_size);
	mutex_unlock(&wb->lock);
	return ret;
}

int bch2_btree_write_buffer_resize(struct bch_fs *c, size_t new_size)
{
	struct btree_write_buffer *wb = &c->btree_write_buffer;

	return wb_keys_resize(&wb->flushing, new_size) ?:
		wb_keys_resize(&wb->inc, new_size);
}

void bch2_fs_btree_write_buffer_exit(struct bch_fs *c)
{
	struct btree_write_buffer *wb = &c->btree_write_buffer;

	BUG_ON((wb->inc.keys.nr || wb->flushing.keys.nr) &&
	       !bch2_journal_error(&c->journal));

	darray_exit(&wb->sorted);
	darray_exit(&wb->flushing.keys);
	darray_exit(&wb->inc.keys);
}

int bch2_fs_btree_write_buffer_init(struct bch_fs *c)
{
	struct btree_write_buffer *wb = &c->btree_write_buffer;

	mutex_init(&wb->inc.lock);
	mutex_init(&wb->flushing.lock);
	INIT_WORK(&wb->flush_work, bch2_btree_write_buffer_flush_work);

	/* Will be resized by journal as needed: */
	unsigned initial_size = 1 << 16;

	return  darray_make_room(&wb->inc.keys, initial_size) ?:
		darray_make_room(&wb->flushing.keys, initial_size) ?:
		darray_make_room(&wb->sorted, initial_size);
}
