Commit b101fbf9a403f38556ed9e6d3b293c73733465e2

Vicent Martí 2013-01-22T18:55:56

Merge pull request #1271 from libgit2/global-settings Global options setter

diff --git a/include/git2/common.h b/include/git2/common.h
index 7a4c54c..7e7c7e3 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -123,6 +123,29 @@ enum {
  */
 GIT_EXTERN(int) git_libgit2_capabilities(void);
 
+
+enum {
+	GIT_OPT_MWINDOW_SIZE,
+	GIT_OPT_MWINDOW_MAPPED_LIMIT
+};
+
+/**
+ * Set or query a library global option
+ *
+ * Available options:
+ *
+ *	opts(GIT_OPT_MWINDOW_SIZE, size_t):
+ *		set the maximum mmap window size
+ *
+ *	opts(GIT_OPT_MWINDOW_MAPPED_LIMIT, size_t):
+ *		set the maximum amount of memory that can be mapped at any time
+ *		by the library
+ *
+ *	@param option Option key
+ *	@param ... value to set the option
+ */
+GIT_EXTERN(void) git_libgit2_opts(int option, ...);
+
 /** @} */
 GIT_END_DECL
 
diff --git a/src/mwindow.c b/src/mwindow.c
index e3043c3..cb2ef78 100644
--- a/src/mwindow.c
+++ b/src/mwindow.c
@@ -20,17 +20,8 @@
 #define DEFAULT_MAPPED_LIMIT \
 	((1024 * 1024) * (sizeof(void*) >= 8 ? 8192ULL : 256UL))
 
-/*
- * These are the global options for mmmap limits.
- * TODO: allow the user to change these
- */
-static struct {
-	size_t window_size;
-	size_t mapped_limit;
-} _mw_options = {
-	DEFAULT_WINDOW_SIZE,
-	DEFAULT_MAPPED_LIMIT,
-};
+size_t git_mwindow__window_size = DEFAULT_WINDOW_SIZE;
+size_t git_mwindow__mapped_limit = DEFAULT_MAPPED_LIMIT;
 
 /* Whenever you want to read or modify this, grab git__mwindow_mutex */
 static git_mwindow_ctl mem_ctl;
@@ -166,7 +157,7 @@ static git_mwindow *new_window(
 	git_off_t offset)
 {
 	git_mwindow_ctl *ctl = &mem_ctl;
-	size_t walign = _mw_options.window_size / 2;
+	size_t walign = git_mwindow__window_size / 2;
 	git_off_t len;
 	git_mwindow *w;
 
@@ -179,16 +170,16 @@ static git_mwindow *new_window(
 	w->offset = (offset / walign) * walign;
 
 	len = size - w->offset;
-	if (len > (git_off_t)_mw_options.window_size)
-		len = (git_off_t)_mw_options.window_size;
+	if (len > (git_off_t)git_mwindow__window_size)
+		len = (git_off_t)git_mwindow__window_size;
 
 	ctl->mapped += (size_t)len;
 
-	while (_mw_options.mapped_limit < ctl->mapped &&
+	while (git_mwindow__mapped_limit < ctl->mapped &&
 			git_mwindow_close_lru(mwf) == 0) /* nop */;
 
 	/*
-	 * We treat _mw_options.mapped_limit as a soft limit. If we can't find a
+	 * We treat `mapped_limit` as a soft limit. If we can't find a
 	 * window to close and are above the limit, we still mmap the new
 	 * window.
 	 */
diff --git a/src/util.c b/src/util.c
index 30c4dc6..243748a 100644
--- a/src/util.c
+++ b/src/util.c
@@ -34,6 +34,29 @@ int git_libgit2_capabilities()
 	;
 }
 
+/* Declarations for tuneable settings */
+extern size_t git_mwindow__window_size;
+extern size_t git_mwindow__mapped_limit;
+
+void git_libgit2_opts(int key, ...)
+{
+	va_list ap;
+
+	va_start(ap, key);
+
+	switch(key) {
+	case GIT_OPT_MWINDOW_SIZE:
+		git_mwindow__window_size = va_arg(ap, size_t);
+		break;
+
+	case GIT_OPT_MWINDOW_MAPPED_LIMIT:
+		git_mwindow__mapped_limit = va_arg(ap, size_t);
+		break;
+	}
+
+	va_end(ap);
+}
+
 void git_strarray_free(git_strarray *array)
 {
 	size_t i;