[PATCH 1/5] vinyl: factor out function to lookup key in page

Vladimir Davydov vdavydov.dev at gmail.com
Wed May 29 18:12:47 MSK 2019


This function is a part of the run iterator API so we can't use it in
a reader thread. Let's make it an independent helper. As a good side
effect, we can now reuse it in the slice stream implementation.
---
 src/box/vy_run.c | 105 +++++++++++++++++++++++--------------------------------
 1 file changed, 44 insertions(+), 61 deletions(-)

diff --git a/src/box/vy_run.c b/src/box/vy_run.c
index 3b38aac6..84e0f50b 100644
--- a/src/box/vy_run.c
+++ b/src/box/vy_run.c
@@ -744,6 +744,41 @@ vy_page_stmt(struct vy_page *page, uint32_t stmt_no,
 }
 
 /**
+ * Binary search in page
+ * In terms of STL, makes lower_bound for EQ,GE,LT and upper_bound for GT,LE
+ * Additionally *equal_key argument is set to true if the found value is
+ * equal to given key (untouched otherwise)
+ * @retval position in the page
+ */
+static uint32_t
+vy_page_find_key(struct vy_page *page, struct vy_entry key,
+		 struct key_def *cmp_def, struct tuple_format *format,
+		 enum iterator_type iterator_type, bool *equal_key)
+{
+	uint32_t beg = 0;
+	uint32_t end = page->row_count;
+	/* for upper bound we change zero comparison result to -1 */
+	int zero_cmp = (iterator_type == ITER_GT ||
+			iterator_type == ITER_LE ? -1 : 0);
+	while (beg != end) {
+		uint32_t mid = beg + (end - beg) / 2;
+		struct vy_entry fnd_key = vy_page_stmt(page, mid, cmp_def,
+						       format);
+		if (fnd_key.stmt == NULL)
+			return end;
+		int cmp = vy_entry_compare(fnd_key, key, cmp_def);
+		cmp = cmp ? cmp : zero_cmp;
+		*equal_key = *equal_key || cmp == 0;
+		if (cmp < 0)
+			beg = mid + 1;
+		else
+			end = mid;
+		tuple_unref(fnd_key.stmt);
+	}
+	return end;
+}
+
+/**
  * End iteration and free cached data.
  */
 static void
@@ -1055,42 +1090,6 @@ vy_run_iterator_read(struct vy_run_iterator *itr,
 }
 
 /**
- * Binary search in page
- * In terms of STL, makes lower_bound for EQ,GE,LT and upper_bound for GT,LE
- * Additionally *equal_key argument is set to true if the found value is
- * equal to given key (untouched otherwise)
- * @retval position in the page
- */
-static uint32_t
-vy_run_iterator_search_in_page(struct vy_run_iterator *itr,
-			       enum iterator_type iterator_type,
-			       struct vy_entry key,
-			       struct vy_page *page, bool *equal_key)
-{
-	uint32_t beg = 0;
-	uint32_t end = page->row_count;
-	/* for upper bound we change zero comparison result to -1 */
-	int zero_cmp = (iterator_type == ITER_GT ||
-			iterator_type == ITER_LE ? -1 : 0);
-	while (beg != end) {
-		uint32_t mid = beg + (end - beg) / 2;
-		struct vy_entry fnd_key = vy_page_stmt(page, mid, itr->cmp_def,
-						       itr->format);
-		if (fnd_key.stmt == NULL)
-			return end;
-		int cmp = vy_entry_compare(fnd_key, key, itr->cmp_def);
-		cmp = cmp ? cmp : zero_cmp;
-		*equal_key = *equal_key || cmp == 0;
-		if (cmp < 0)
-			beg = mid + 1;
-		else
-			end = mid;
-		tuple_unref(fnd_key.stmt);
-	}
-	return end;
-}
-
-/**
  * Binary search in a run for the given key.
  * In terms of STL, makes lower_bound for EQ,GE,LT and upper_bound for GT,LE
  * Resulting wide position is stored it *pos argument
@@ -1116,9 +1115,9 @@ vy_run_iterator_search(struct vy_run_iterator *itr,
 	if (rc != 0)
 		return rc;
 	bool equal_in_page = false;
-	pos->pos_in_page = vy_run_iterator_search_in_page(itr, iterator_type,
-							  key, page,
-							  &equal_in_page);
+	pos->pos_in_page = vy_page_find_key(page, key, itr->cmp_def,
+					    itr->format, iterator_type,
+					    &equal_in_page);
 	if (pos->pos_in_page == page->row_count) {
 		pos->page_no++;
 		pos->pos_in_page = 0;
@@ -2600,28 +2599,12 @@ vy_slice_stream_search(struct vy_stmt_stream *virt_stream)
 	if (vy_slice_stream_read_page(stream) != 0)
 		return -1;
 
-	/**
-	 * Binary search in page. Find the first position in page with
-	 * tuple >= stream->slice->begin.
-	 */
-	uint32_t beg = 0;
-	uint32_t end = stream->page->row_count;
-	while (beg != end) {
-		uint32_t mid = beg + (end - beg) / 2;
-		struct vy_entry fnd_key = vy_page_stmt(stream->page, mid,
-						       stream->cmp_def,
-						       stream->format);
-		if (fnd_key.stmt == NULL)
-			return -1;
-		int cmp = vy_entry_compare(fnd_key, stream->slice->begin,
-					   stream->cmp_def);
-		if (cmp < 0)
-			beg = mid + 1;
-		else
-			end = mid;
-		tuple_unref(fnd_key.stmt);
-	}
-	stream->pos_in_page = end;
+	bool unused;
+	stream->pos_in_page = vy_page_find_key(stream->page,
+					       stream->slice->begin,
+					       stream->cmp_def,
+					       stream->format,
+					       ITER_GE, &unused);
 
 	if (stream->pos_in_page == stream->page->row_count) {
 		/* The first tuple is in the beginning of the next page */
-- 
2.11.0




More information about the Tarantool-patches mailing list