<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<id>tag:old.nabble.com,2006:forum-794</id>
	<title>Nabble - RRDTool - Dev</title>
	<updated>2009-11-23T00:52:11Z</updated>
	<link rel="self" type="application/atom+xml" href="http://old.nabble.com/RRDTool---Dev-f794.xml" />
	<link rel="alternate" type="text/html" href="http://old.nabble.com/RRDTool---Dev-f794.html" />
	<subtitle type="html"></subtitle>
	
<entry>
	<id>tag:old.nabble.com,2006:post-26474545</id>
	<title>Hi~! would you mind if i ask you to use RRDtool?</title>
	<published>2009-11-23T00:52:11Z</published>
	<updated>2009-11-23T00:52:11Z</updated>
	<author>
		<name>성노섭</name>
	</author>
	<content type="html">&lt;IMG SRC=&quot;http://mail.nate.com/NateConfirmMgr.php?act=confirm&amp;key=1258966331_rrd-developers@lists.oetiker.ch&amp;from=|PROFILE1|24|75|36|tjdshtjq@nate.com&quot; height=&quot;0&quot; width=&quot;0&quot;&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;Hi~!!&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;I'm korean who study network in Sungkyunkwan university.&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;Sorry,&amp;nbsp; i&amp;nbsp;don't speak English very well.&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;Anyway, i hope to make a simple network monitoring program using RRdtool and Libpcap&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;I&amp;nbsp;tried to search document that is RRD menual using C API, but got a little information&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;Please, help me.&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;i'dont understand how to use a function of RRDtool in real network?&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;read the example..&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;//&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;char * updateparams[]={&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;&amp;quot;rrdupdate&amp;quot;,&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;&amp;quot;myfile.rrd&amp;quot;,&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;&amp;quot;0:42&amp;quot;,&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;NULL&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;};&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;rrd_update(3,updateparams);&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;//&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;rrd_crate and rrd_graph are almost same..&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;But it's not enough.. T_T&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;I&amp;nbsp;hope to know a code...&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;Now, there are a many example, but i don't know a real code with libpcap.. T_T&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;I already completed coding to capture packet using libpcap&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;Please, help me.. T_T&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;Thank you, best regards&lt;/p&gt;&lt;p style=&quot;MARGIN: 3px 0px 2px&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;br&gt;
&lt;br&gt;
&lt;br /&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26474545&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Hi%7E%21-would-you-mind-if-i-ask-you-to-use-RRDtool--tp26474545p26474545.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26268101</id>
	<title>Re: [PATCH 1/2] Add utility functions to allocate pointers in variable size chunks.</title>
	<published>2009-11-09T07:19:33Z</published>
	<updated>2009-11-09T07:19:33Z</updated>
	<author>
		<name>kevin brintnall</name>
	</author>
	<content type="html">On Mon, Nov 09, 2009 at 09:57:43AM +0100, Tobias Oetiker wrote:
&lt;br&gt;&amp;gt; Hi Kevin,
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; since 1.4.x is now out, I would like to hold off on adding new
&lt;br&gt;&amp;gt; public functions to the 1.4 branche ... these would go into the new
&lt;br&gt;&amp;gt; trunk. or is there also a bug-fix component to this change ?
&lt;br&gt;&lt;br&gt;Tobi,
&lt;br&gt;&lt;br&gt;This improves performance for implementations where realloc() may be
&lt;br&gt;expensive.. &amp;nbsp;It causes the realloc() for cache_item_t.values to be in
&lt;br&gt;larger chunks, and less frequent.
&lt;br&gt;&lt;br&gt;This is in response to Thorsten's performance testing, where he sees CPU
&lt;br&gt;spikes at specific times after start-up, when his cache_item_t.values
&lt;br&gt;arrays all simultaneously cross some size threshold.
&lt;br&gt;&lt;br&gt;Up to you.
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;&amp;nbsp;kevin brintnall =~ /&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26268101&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;kbrint@...&lt;/a&gt;/
&lt;br&gt;&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; cheers
&lt;br&gt;&amp;gt; tobi
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Oct 31 kevin brintnall wrote:
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; &amp;gt; ---
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;doc/librrd.pod &amp;nbsp;| &amp;nbsp; 18 ++++++++++++++++++
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;src/rrd.h &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;4 ++++
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;src/rrd_utils.c | &amp;nbsp; 53 ++++++++++++++++++++++++++++++++++++++++++-----------
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;3 files changed, 64 insertions(+), 11 deletions(-)
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; diff --git a/doc/librrd.pod b/doc/librrd.pod
&lt;br&gt;&amp;gt; &amp;gt; index 038746c..396e50c 100644
&lt;br&gt;&amp;gt; &amp;gt; --- a/doc/librrd.pod
&lt;br&gt;&amp;gt; &amp;gt; +++ b/doc/librrd.pod
&lt;br&gt;&amp;gt; &amp;gt; @@ -81,6 +81,16 @@ end of the new C&amp;lt;dest&amp;gt;. &amp;nbsp;Returns 1 on success, 0 on failure.
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!rrd_add_ptr(&amp;arr, &amp;arr_size, elem))
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;handle_failure();
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; +=item B&amp;lt;rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src, size_t *alloc, size_t chunk)&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; &amp;gt; +Like C&amp;lt;rrd_add_ptr&amp;gt;, except the destination is allocated in chunks of
&lt;br&gt;&amp;gt; &amp;gt; +C&amp;lt;chunk&amp;gt;. &amp;nbsp;C&amp;lt;alloc&amp;gt; points to the number of entries allocated, whereas
&lt;br&gt;&amp;gt; &amp;gt; +C&amp;lt;dest_size&amp;gt; points to the number of valid pointers. &amp;nbsp;If more pointers are
&lt;br&gt;&amp;gt; &amp;gt; +needed, C&amp;lt;chunk&amp;gt; pointers are allocated and C&amp;lt;alloc&amp;gt; is increased
&lt;br&gt;&amp;gt; &amp;gt; +accordingly. &amp;nbsp;C&amp;lt;alloc&amp;gt; must be E&amp;lt;gt&amp;gt;= C&amp;lt;dest_size&amp;gt;.
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; &amp;gt; +This method improves performance on hosts with expensive C&amp;lt;realloc()&amp;gt;.
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;=item B&amp;lt;rrd_add_strdup(char ***dest, size_t *dest_size, char *src)&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;Like C&amp;lt;rrd_add_ptr&amp;gt;, except adds a C&amp;lt;strdup&amp;gt; of the source string.
&lt;br&gt;&amp;gt; &amp;gt; @@ -91,6 +101,14 @@ Like C&amp;lt;rrd_add_ptr&amp;gt;, except adds a C&amp;lt;strdup&amp;gt; of the source string.
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!rrd_add_strdup(&amp;arr, &amp;arr_size, str))
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;handle_failure();
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; +=item B&amp;lt;rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src, size_t *alloc, size_t chunk)&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; &amp;gt; +Like C&amp;lt;rrd_add_strdup&amp;gt;, except the destination is allocated in chunks of
&lt;br&gt;&amp;gt; &amp;gt; +C&amp;lt;chunk&amp;gt;. &amp;nbsp;C&amp;lt;alloc&amp;gt; points to the number of entries allocated, whereas
&lt;br&gt;&amp;gt; &amp;gt; +C&amp;lt;dest_size&amp;gt; points to the number of valid pointers. &amp;nbsp;If more pointers are
&lt;br&gt;&amp;gt; &amp;gt; +needed, C&amp;lt;chunk&amp;gt; pointers are allocated and C&amp;lt;alloc&amp;gt; is increased
&lt;br&gt;&amp;gt; &amp;gt; +accordingly. &amp;nbsp;C&amp;lt;alloc&amp;gt; must be E&amp;lt;gt&amp;gt;= C&amp;lt;dest_size&amp;gt;.
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;=item B&amp;lt;rrd_free_ptrs(void ***src, size_t *cnt)&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;Free an array of pointers allocated by C&amp;lt;rrd_add_ptr&amp;gt; or
&lt;br&gt;&amp;gt; &amp;gt; diff --git a/src/rrd.h b/src/rrd.h
&lt;br&gt;&amp;gt; &amp;gt; index ce7e749..6008794 100644
&lt;br&gt;&amp;gt; &amp;gt; --- a/src/rrd.h
&lt;br&gt;&amp;gt; &amp;gt; +++ b/src/rrd.h
&lt;br&gt;&amp;gt; &amp;gt; @@ -333,8 +333,12 @@ int &amp;nbsp; &amp;nbsp; &amp;nbsp; rrd_proc_start_end(
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;long rrd_random(void);
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src,
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;size_t *alloc, size_t chunk);
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;int rrd_add_ptr(void ***dest, size_t *dest_size, void *src);
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;int rrd_add_strdup(char ***dest, size_t *dest_size, char *src);
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src,
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t *alloc, size_t chunk);
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;void rrd_free_ptrs(void ***src, size_t *cnt);
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;int rrd_mkdir_p(const char *pathname, mode_t mode);
&lt;br&gt;&amp;gt; &amp;gt; diff --git a/src/rrd_utils.c b/src/rrd_utils.c
&lt;br&gt;&amp;gt; &amp;gt; index 3936cff..6853c66 100644
&lt;br&gt;&amp;gt; &amp;gt; --- a/src/rrd_utils.c
&lt;br&gt;&amp;gt; &amp;gt; +++ b/src/rrd_utils.c
&lt;br&gt;&amp;gt; &amp;gt; @@ -50,29 +50,53 @@ long rrd_random(void)
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;return random();
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; -/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
&lt;br&gt;&amp;gt; &amp;gt; - * realloc as necessary. &amp;nbsp;returns 1 on success, 0 on failure.
&lt;br&gt;&amp;gt; &amp;gt; +/* rrd_add_ptr_chunk: add a pointer to a dynamically sized array of
&lt;br&gt;&amp;gt; &amp;gt; + * pointers, realloc as necessary in multiples of &amp;quot;chunk&amp;quot;.
&lt;br&gt;&amp;gt; &amp;gt; + *
&lt;br&gt;&amp;gt; &amp;gt; + * &amp;quot;alloc&amp;quot; is the number of pointers allocated
&lt;br&gt;&amp;gt; &amp;gt; + * &amp;quot;dest_size&amp;quot; is the number of valid pointers
&lt;br&gt;&amp;gt; &amp;gt; + *
&lt;br&gt;&amp;gt; &amp;gt; + * returns 1 on success, 0 on failure.
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; */
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; -int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
&lt;br&gt;&amp;gt; &amp;gt; +int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src,
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;size_t *alloc, size_t chunk)
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;void **temp;
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;assert(dest != NULL);
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;assert(alloc != NULL);
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;assert(*alloc &amp;gt;= *dest_size);
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; - &amp;nbsp; &amp;nbsp;temp = (void **) rrd_realloc(*dest, (*dest_size+1) * sizeof(*dest));
&lt;br&gt;&amp;gt; &amp;gt; - &amp;nbsp; &amp;nbsp;if (!temp)
&lt;br&gt;&amp;gt; &amp;gt; - &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;if (*alloc == *dest_size)
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;temp = (void **) rrd_realloc(*dest, (*alloc+chunk) * sizeof(*dest));
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!temp)
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; - &amp;nbsp; &amp;nbsp;*dest = temp;
&lt;br&gt;&amp;gt; &amp;gt; - &amp;nbsp; &amp;nbsp;temp[*dest_size] = src;
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*dest = temp;
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*alloc += chunk;
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;(*dest)[*dest_size] = src;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;(*dest_size)++;
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 1;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; -/* like rrd_add_ptr, but calls strdup() on a string first. */
&lt;br&gt;&amp;gt; &amp;gt; -int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
&lt;br&gt;&amp;gt; &amp;gt; +/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
&lt;br&gt;&amp;gt; &amp;gt; + * realloc as necessary. &amp;nbsp;returns 1 on success, 0 on failure.
&lt;br&gt;&amp;gt; &amp;gt; + */
&lt;br&gt;&amp;gt; &amp;gt; +int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
&lt;br&gt;&amp;gt; &amp;gt; +{
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;size_t alloc = *dest_size;
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;return rrd_add_ptr_chunk(dest, dest_size, src, &amp;alloc, 1);
&lt;br&gt;&amp;gt; &amp;gt; +}
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; &amp;gt; +/* like rrd_add_ptr_chunk, but calls strdup() on a string first. */
&lt;br&gt;&amp;gt; &amp;gt; +int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src,
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t *alloc, size_t chunk)
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;char *dup_src;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;int add_ok;
&lt;br&gt;&amp;gt; &amp;gt; @@ -84,13 +108,20 @@ int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!dup_src)
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; - &amp;nbsp; &amp;nbsp;add_ok = rrd_add_ptr((void ***)dest, dest_size, (void *)dup_src);
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;add_ok = rrd_add_ptr_chunk((void ***)dest, dest_size, (void *)dup_src, alloc, chunk);
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!add_ok)
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;free(dup_src);
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;return add_ok;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; +int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
&lt;br&gt;&amp;gt; &amp;gt; +{
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;size_t alloc = *dest_size;
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; &amp;gt; + &amp;nbsp; &amp;nbsp;return rrd_add_strdup_chunk(dest, dest_size, src, &amp;alloc, 1);
&lt;br&gt;&amp;gt; &amp;gt; +}
&lt;br&gt;&amp;gt; &amp;gt; +
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;void rrd_free_ptrs(void ***src, size_t *cnt)
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;void **sp;
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; -- 
&lt;br&gt;&amp;gt; Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
&lt;br&gt;&amp;gt; &lt;a href=&quot;http://it.oetiker.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://it.oetiker.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26268101&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tobi@...&lt;/a&gt; ++41 62 775 9902 / sb: -9900
&lt;/div&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26268101&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH-1-2--Add-utility-functions-to-allocate-pointers-in-variable-size-chunks.-tp26144946p26268101.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26263016</id>
	<title>Re: [PATCH 1/2] Add utility functions to allocate pointers in variable size chunks.</title>
	<published>2009-11-09T00:57:43Z</published>
	<updated>2009-11-09T00:57:43Z</updated>
	<author>
		<name>Tobias Oetiker-3</name>
	</author>
	<content type="html">Hi Kevin,
&lt;br&gt;&lt;br&gt;since 1.4.x is now out, I would like to hold off on adding new
&lt;br&gt;public functions to the 1.4 branche ... these would go into the new
&lt;br&gt;trunk. or is there also a bug-fix component to this change ?
&lt;br&gt;&lt;br&gt;cheers
&lt;br&gt;tobi
&lt;br&gt;&lt;br&gt;Oct 31 kevin brintnall wrote:
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; ---
&lt;br&gt;&amp;gt; &amp;nbsp;doc/librrd.pod &amp;nbsp;| &amp;nbsp; 18 ++++++++++++++++++
&lt;br&gt;&amp;gt; &amp;nbsp;src/rrd.h &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;4 ++++
&lt;br&gt;&amp;gt; &amp;nbsp;src/rrd_utils.c | &amp;nbsp; 53 ++++++++++++++++++++++++++++++++++++++++++-----------
&lt;br&gt;&amp;gt; &amp;nbsp;3 files changed, 64 insertions(+), 11 deletions(-)
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; diff --git a/doc/librrd.pod b/doc/librrd.pod
&lt;br&gt;&amp;gt; index 038746c..396e50c 100644
&lt;br&gt;&amp;gt; --- a/doc/librrd.pod
&lt;br&gt;&amp;gt; +++ b/doc/librrd.pod
&lt;br&gt;&amp;gt; @@ -81,6 +81,16 @@ end of the new C&amp;lt;dest&amp;gt;. &amp;nbsp;Returns 1 on success, 0 on failure.
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!rrd_add_ptr(&amp;arr, &amp;arr_size, elem))
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;handle_failure();
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; +=item B&amp;lt;rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src, size_t *alloc, size_t chunk)&amp;gt;
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; +Like C&amp;lt;rrd_add_ptr&amp;gt;, except the destination is allocated in chunks of
&lt;br&gt;&amp;gt; +C&amp;lt;chunk&amp;gt;. &amp;nbsp;C&amp;lt;alloc&amp;gt; points to the number of entries allocated, whereas
&lt;br&gt;&amp;gt; +C&amp;lt;dest_size&amp;gt; points to the number of valid pointers. &amp;nbsp;If more pointers are
&lt;br&gt;&amp;gt; +needed, C&amp;lt;chunk&amp;gt; pointers are allocated and C&amp;lt;alloc&amp;gt; is increased
&lt;br&gt;&amp;gt; +accordingly. &amp;nbsp;C&amp;lt;alloc&amp;gt; must be E&amp;lt;gt&amp;gt;= C&amp;lt;dest_size&amp;gt;.
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; +This method improves performance on hosts with expensive C&amp;lt;realloc()&amp;gt;.
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; &amp;nbsp;=item B&amp;lt;rrd_add_strdup(char ***dest, size_t *dest_size, char *src)&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp;Like C&amp;lt;rrd_add_ptr&amp;gt;, except adds a C&amp;lt;strdup&amp;gt; of the source string.
&lt;br&gt;&amp;gt; @@ -91,6 +101,14 @@ Like C&amp;lt;rrd_add_ptr&amp;gt;, except adds a C&amp;lt;strdup&amp;gt; of the source string.
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!rrd_add_strdup(&amp;arr, &amp;arr_size, str))
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;handle_failure();
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; +=item B&amp;lt;rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src, size_t *alloc, size_t chunk)&amp;gt;
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; +Like C&amp;lt;rrd_add_strdup&amp;gt;, except the destination is allocated in chunks of
&lt;br&gt;&amp;gt; +C&amp;lt;chunk&amp;gt;. &amp;nbsp;C&amp;lt;alloc&amp;gt; points to the number of entries allocated, whereas
&lt;br&gt;&amp;gt; +C&amp;lt;dest_size&amp;gt; points to the number of valid pointers. &amp;nbsp;If more pointers are
&lt;br&gt;&amp;gt; +needed, C&amp;lt;chunk&amp;gt; pointers are allocated and C&amp;lt;alloc&amp;gt; is increased
&lt;br&gt;&amp;gt; +accordingly. &amp;nbsp;C&amp;lt;alloc&amp;gt; must be E&amp;lt;gt&amp;gt;= C&amp;lt;dest_size&amp;gt;.
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; &amp;nbsp;=item B&amp;lt;rrd_free_ptrs(void ***src, size_t *cnt)&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp;Free an array of pointers allocated by C&amp;lt;rrd_add_ptr&amp;gt; or
&lt;br&gt;&amp;gt; diff --git a/src/rrd.h b/src/rrd.h
&lt;br&gt;&amp;gt; index ce7e749..6008794 100644
&lt;br&gt;&amp;gt; --- a/src/rrd.h
&lt;br&gt;&amp;gt; +++ b/src/rrd.h
&lt;br&gt;&amp;gt; @@ -333,8 +333,12 @@ int &amp;nbsp; &amp;nbsp; &amp;nbsp; rrd_proc_start_end(
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;long rrd_random(void);
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src,
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;size_t *alloc, size_t chunk);
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;int rrd_add_ptr(void ***dest, size_t *dest_size, void *src);
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;int rrd_add_strdup(char ***dest, size_t *dest_size, char *src);
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src,
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t *alloc, size_t chunk);
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;void rrd_free_ptrs(void ***src, size_t *cnt);
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;int rrd_mkdir_p(const char *pathname, mode_t mode);
&lt;br&gt;&amp;gt; diff --git a/src/rrd_utils.c b/src/rrd_utils.c
&lt;br&gt;&amp;gt; index 3936cff..6853c66 100644
&lt;br&gt;&amp;gt; --- a/src/rrd_utils.c
&lt;br&gt;&amp;gt; +++ b/src/rrd_utils.c
&lt;br&gt;&amp;gt; @@ -50,29 +50,53 @@ long rrd_random(void)
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;return random();
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; -/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
&lt;br&gt;&amp;gt; - * realloc as necessary. &amp;nbsp;returns 1 on success, 0 on failure.
&lt;br&gt;&amp;gt; +/* rrd_add_ptr_chunk: add a pointer to a dynamically sized array of
&lt;br&gt;&amp;gt; + * pointers, realloc as necessary in multiples of &amp;quot;chunk&amp;quot;.
&lt;br&gt;&amp;gt; + *
&lt;br&gt;&amp;gt; + * &amp;quot;alloc&amp;quot; is the number of pointers allocated
&lt;br&gt;&amp;gt; + * &amp;quot;dest_size&amp;quot; is the number of valid pointers
&lt;br&gt;&amp;gt; + *
&lt;br&gt;&amp;gt; + * returns 1 on success, 0 on failure.
&lt;br&gt;&amp;gt; &amp;nbsp; */
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; -int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
&lt;br&gt;&amp;gt; +int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src,
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;size_t *alloc, size_t chunk)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;void **temp;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;assert(dest != NULL);
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;assert(alloc != NULL);
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;assert(*alloc &amp;gt;= *dest_size);
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; - &amp;nbsp; &amp;nbsp;temp = (void **) rrd_realloc(*dest, (*dest_size+1) * sizeof(*dest));
&lt;br&gt;&amp;gt; - &amp;nbsp; &amp;nbsp;if (!temp)
&lt;br&gt;&amp;gt; - &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;if (*alloc == *dest_size)
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;{
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;temp = (void **) rrd_realloc(*dest, (*alloc+chunk) * sizeof(*dest));
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!temp)
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; - &amp;nbsp; &amp;nbsp;*dest = temp;
&lt;br&gt;&amp;gt; - &amp;nbsp; &amp;nbsp;temp[*dest_size] = src;
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*dest = temp;
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*alloc += chunk;
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;(*dest)[*dest_size] = src;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;(*dest_size)++;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 1;
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; -/* like rrd_add_ptr, but calls strdup() on a string first. */
&lt;br&gt;&amp;gt; -int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
&lt;br&gt;&amp;gt; +/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
&lt;br&gt;&amp;gt; + * realloc as necessary. &amp;nbsp;returns 1 on success, 0 on failure.
&lt;br&gt;&amp;gt; + */
&lt;br&gt;&amp;gt; +int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
&lt;br&gt;&amp;gt; +{
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;size_t alloc = *dest_size;
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;return rrd_add_ptr_chunk(dest, dest_size, src, &amp;alloc, 1);
&lt;br&gt;&amp;gt; +}
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; +/* like rrd_add_ptr_chunk, but calls strdup() on a string first. */
&lt;br&gt;&amp;gt; +int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src,
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t *alloc, size_t chunk)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;char *dup_src;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;int add_ok;
&lt;br&gt;&amp;gt; @@ -84,13 +108,20 @@ int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!dup_src)
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; - &amp;nbsp; &amp;nbsp;add_ok = rrd_add_ptr((void ***)dest, dest_size, (void *)dup_src);
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;add_ok = rrd_add_ptr_chunk((void ***)dest, dest_size, (void *)dup_src, alloc, chunk);
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!add_ok)
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;free(dup_src);
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;return add_ok;
&lt;br&gt;&amp;gt; &amp;nbsp;}
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; +int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
&lt;br&gt;&amp;gt; +{
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;size_t alloc = *dest_size;
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;return rrd_add_strdup_chunk(dest, dest_size, src, &amp;alloc, 1);
&lt;br&gt;&amp;gt; +}
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; &amp;nbsp;void rrd_free_ptrs(void ***src, size_t *cnt)
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;void **sp;
&lt;br&gt;&amp;gt;
&lt;/div&gt;&lt;br&gt;-- 
&lt;br&gt;Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
&lt;br&gt;&lt;a href=&quot;http://it.oetiker.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://it.oetiker.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26263016&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tobi@...&lt;/a&gt; ++41 62 775 9902 / sb: -9900
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26263016&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH-1-2--Add-utility-functions-to-allocate-pointers-in-variable-size-chunks.-tp26144946p26263016.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26233210</id>
	<title>Re: patch to do vertical gradients</title>
	<published>2009-11-06T06:49:28Z</published>
	<updated>2009-11-06T06:49:28Z</updated>
	<author>
		<name>Rian Shelley</name>
	</author>
	<content type="html">On Fri, Nov 6, 2009 at 7:20 AM, Mark Mills &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26233210&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;extremely@...&lt;/a&gt;&amp;gt; wrote:
&lt;br&gt;&amp;gt; If it was used to carry information, one that might help would be scale
&lt;br&gt;&amp;gt; differences. I have had issues in the past where my boss at the time
&lt;br&gt;&amp;gt; freaked out when a graph spiked and we had to point out that the one he
&lt;br&gt;&amp;gt; was looking at had spiked from bits to kbits... not from mbits to gbits.
&lt;br&gt;&amp;gt; ;-) A way to color the scale in the area (logarithmically?) would help
&lt;br&gt;&amp;gt; when scanning graphs quickly. It wouldn't give the same cool fire effect
&lt;br&gt;&amp;gt; but &amp;quot;ripples&amp;quot; in the area paint could effectively replace the need for
&lt;br&gt;&amp;gt; grid lines.
&lt;br&gt;&lt;br&gt;Thats one of the reasons I wrote it. A negative height would be
&lt;br&gt;aligned to the x axis, so that increasing values on the line change to
&lt;br&gt;the next color, ie a gradient from green to red. Of course, to be
&lt;br&gt;really useful, I would need to change it so that the height was
&lt;br&gt;relative to the data set, and not given in pixels. I'll have to see
&lt;br&gt;how to do that. gfx_area_fit maybe?
&lt;br&gt;&lt;br&gt;&amp;gt; I'd also recommend that the default second color be set to the graph
&lt;br&gt;&amp;gt; background color with the transparency set to 0x20 and not be forced to
&lt;br&gt;&amp;gt; #000000. Might as well make it do something cool by default no matter
&lt;br&gt;&amp;gt; what color scheme they use.
&lt;br&gt;&lt;br&gt;Maybe. I figured it didn't matter much what the color was if the alpha
&lt;br&gt;was zero. That way it always appeared to fade into whatever is behind
&lt;br&gt;it, be it the background or another AREA. I'll have to play with it
&lt;br&gt;and see what it looks like.
&lt;br&gt;&lt;br&gt;&amp;gt; Also, I'm jealous of Rian because I've been wanting to write this patch
&lt;br&gt;&amp;gt; for like 5-6 years and never had the time. ;-) It looks even better than
&lt;br&gt;&amp;gt; I hoped. I'm looking forward to this being in the main build.
&lt;br&gt;&lt;br&gt;All the heavy lifting is done by cairo :D. All I did was allow the
&lt;br&gt;source pattern to be a gradient as well as a solid color. I think the
&lt;br&gt;other option is to make the source pattern another image.
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;rian
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26233210&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/patch-to-do-vertical-gradients-tp26220087p26233210.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26232868</id>
	<title>Re: patch to do vertical gradients</title>
	<published>2009-11-06T06:20:54Z</published>
	<updated>2009-11-06T06:20:54Z</updated>
	<author>
		<name>Mark Mills</name>
	</author>
	<content type="html">Tobias Oetiker wrote:
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; thanks for this ... it looks cool ... quersion though, is there
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; some information carying capability in this feature ?
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;If it was used to carry information, one that might help would be scale
&lt;br&gt;differences. I have had issues in the past where my boss at the time
&lt;br&gt;freaked out when a graph spiked and we had to point out that the one he
&lt;br&gt;was looking at had spiked from bits to kbits... not from mbits to gbits.
&lt;br&gt;;-) A way to color the scale in the area (logarithmically?) would help
&lt;br&gt;when scanning graphs quickly. It wouldn't give the same cool fire effect
&lt;br&gt;but &amp;quot;ripples&amp;quot; in the area paint could effectively replace the need for
&lt;br&gt;grid lines.
&lt;br&gt;&lt;br&gt;&lt;br&gt;I'd also recommend that the default second color be set to the graph
&lt;br&gt;background color with the transparency set to 0x20 and not be forced to
&lt;br&gt;#000000. Might as well make it do something cool by default no matter
&lt;br&gt;what color scheme they use.
&lt;br&gt;&lt;br&gt;Also, I'm jealous of Rian because I've been wanting to write this patch
&lt;br&gt;for like 5-6 years and never had the time. ;-) It looks even better than
&lt;br&gt;I hoped. I'm looking forward to this being in the main build.
&lt;br&gt;&lt;br&gt;--mark
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26232868&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/patch-to-do-vertical-gradients-tp26220087p26232868.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26221443</id>
	<title>Re: patch to do vertical gradients</title>
	<published>2009-11-05T12:10:35Z</published>
	<updated>2009-11-05T12:10:35Z</updated>
	<author>
		<name>Tobias Oetiker-3</name>
	</author>
	<content type="html">Hi Rian,
&lt;br&gt;&lt;br&gt;Today Rian Shelley wrote:
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; This time i remembered to attach the patch :D
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; thanks for this ... it looks cool ... quersion though, is there
&lt;br&gt;&amp;gt; &amp;gt; some information carying capability in this feature ?
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Not really. For the most part, I wanted to add some control over how
&lt;br&gt;&amp;gt; the AREA's were drawn, especially when you have two of them on the
&lt;br&gt;&amp;gt; same graph that keep covering one another, it makes it easier for the
&lt;br&gt;&amp;gt; eye to pick out the two graphs, as opposed to simply using an alpha,
&lt;br&gt;&amp;gt; which gives a solid color that can be mis-interpreted as another
&lt;br&gt;&amp;gt; graph.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I also wanted the ability to make it so that peak values could be
&lt;br&gt;&amp;gt; highlighted in a different color if desired, as in a cpu graph going
&lt;br&gt;&amp;gt; from green through yellow to red.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I haven't thought about making it carry information, although it might
&lt;br&gt;&amp;gt; be neat to show temporal distribution of an average value (ie, turn
&lt;br&gt;&amp;gt; the dataset on its side, and make it represent color instead of
&lt;br&gt;&amp;gt; displacement). I don't really know how to get into that, since all
&lt;br&gt;&amp;gt; I've played with so far is the drawing code.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; can you please also add a patch for the documentation ?
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Hopefully the attached patch will suffice.
&lt;/div&gt;&lt;br&gt;great ... thanks very much
&lt;br&gt;tobi
&lt;br&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; --
&lt;br&gt;&amp;gt; rian
&lt;br&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
&lt;br&gt;&lt;a href=&quot;http://it.oetiker.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://it.oetiker.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26221443&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tobi@...&lt;/a&gt; ++41 62 775 9902 / sb: -9900
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26221443&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/patch-to-do-vertical-gradients-tp26220087p26221443.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26221020</id>
	<title>Re: patch to do vertical gradients</title>
	<published>2009-11-05T11:33:34Z</published>
	<updated>2009-11-05T11:33:34Z</updated>
	<author>
		<name>Rian Shelley</name>
	</author>
	<content type="html">This time i remembered to attach the patch :D
&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;gt; thanks for this ... it looks cool ... quersion though, is there
&lt;br&gt;&amp;gt; some information carying capability in this feature ?
&lt;br&gt;&lt;br&gt;Not really. For the most part, I wanted to add some control over how
&lt;br&gt;the AREA's were drawn, especially when you have two of them on the
&lt;br&gt;same graph that keep covering one another, it makes it easier for the
&lt;br&gt;eye to pick out the two graphs, as opposed to simply using an alpha,
&lt;br&gt;which gives a solid color that can be mis-interpreted as another
&lt;br&gt;graph.
&lt;br&gt;&lt;br&gt;I also wanted the ability to make it so that peak values could be
&lt;br&gt;highlighted in a different color if desired, as in a cpu graph going
&lt;br&gt;from green through yellow to red.
&lt;br&gt;&lt;br&gt;I haven't thought about making it carry information, although it might
&lt;br&gt;be neat to show temporal distribution of an average value (ie, turn
&lt;br&gt;the dataset on its side, and make it represent color instead of
&lt;br&gt;displacement). I don't really know how to get into that, since all
&lt;br&gt;I've played with so far is the drawing code.
&lt;br&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; can you please also add a patch for the documentation ?
&lt;br&gt;&lt;br&gt;Hopefully the attached patch will suffice.
&lt;br&gt;&lt;br&gt;&lt;br&gt;--
&lt;br&gt;rian
&lt;br&gt;&lt;br /&gt;&lt;tt&gt;[grad_doc.patch]&lt;/tt&gt;&lt;br /&gt;&lt;hr align=&quot;left&quot; width=&quot;300&quot; /&gt;&lt;tt&gt;diff -crB rrdtool-1.3.8/doc/rrdgraph_graph.pod ../rrdtool-1.3.8/doc/rrdgraph_graph.pod
&lt;br&gt;*** rrdtool-1.3.8/doc/rrdgraph_graph.pod	Sat Feb 21 02:43:58 2009
&lt;br&gt;--- ../rrdtool-1.3.8/doc/rrdgraph_graph.pod	Thu Nov &amp;nbsp;5 12:23:08 2009
&lt;br&gt;***************
&lt;br&gt;*** 262,267 ****
&lt;br&gt;--- 262,275 ----
&lt;br&gt;&amp;nbsp; See B&amp;lt;LINE&amp;gt;, however the area between the x-axis and the line will
&lt;br&gt;&amp;nbsp; be filled.
&lt;br&gt;&amp;nbsp; 
&lt;br&gt;+ =head3 B&amp;lt;GRAD&amp;gt;B&amp;lt;:&amp;gt;I&amp;lt;value&amp;gt;[B&amp;lt;#&amp;gt;I&amp;lt;color1&amp;gt;[B&amp;lt;#&amp;gt;I&amp;lt;color2&amp;gt;B&amp;lt;:&amp;gt;I&amp;lt;height&amp;gt;][B&amp;lt;:&amp;gt;[I&amp;lt;legend&amp;gt;][B&amp;lt;:STACK&amp;gt;]]
&lt;br&gt;+ 
&lt;br&gt;+ Similar to B&amp;lt;AREA&amp;gt;, except the area between the line and the x-axis will contain a gradient from color1 to color2.
&lt;br&gt;+ 
&lt;br&gt;+ The I&amp;lt;height&amp;gt; parameter can create three different behaviors. If I&amp;lt;height&amp;gt; &amp;gt; 0, then the gradient is a fixed height, starting at the line going down. If I&amp;lt;height&amp;gt; &amp;lt; 0, then the gradient starts at fixed height above the x-axis, going down to the x-axis. If I&amp;lt;height&amp;gt; == 0, then the gradient goes from the line to x-axis. 
&lt;br&gt;+ 
&lt;br&gt;+ If not present, I&amp;lt;color2&amp;gt; defaults to #00000000 and I&amp;lt;height&amp;gt; defaults to 50.
&lt;br&gt;+ 
&lt;br&gt;&amp;nbsp; =head3 B&amp;lt;TICK&amp;gt;B&amp;lt;:&amp;gt;I&amp;lt;vname&amp;gt;B&amp;lt;#&amp;gt;I&amp;lt;rrggbb&amp;gt;[I&amp;lt;aa&amp;gt;][B&amp;lt;:&amp;gt;I&amp;lt;fraction&amp;gt;[B&amp;lt;:&amp;gt;I&amp;lt;legend&amp;gt;]]
&lt;br&gt;&amp;nbsp; 
&lt;br&gt;&amp;nbsp; Plot a tick mark (a vertical line) for each value of I&amp;lt;vname&amp;gt; that is
&lt;br&gt;&lt;/tt&gt;&lt;hr align=&quot;left&quot; width=&quot;300&quot; /&gt;&lt;br /&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26221020&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/patch-to-do-vertical-gradients-tp26220087p26221020.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26221040</id>
	<title>Re: patch to do vertical gradients</title>
	<published>2009-11-05T11:32:20Z</published>
	<updated>2009-11-05T11:32:20Z</updated>
	<author>
		<name>Rian Shelley</name>
	</author>
	<content type="html">&amp;gt; thanks for this ... it looks cool ... quersion though, is there
&lt;br&gt;&amp;gt; some information carying capability in this feature ?
&lt;br&gt;&lt;br&gt;Not really. For the most part, I wanted to add some control over how
&lt;br&gt;the AREA's were drawn, especially when you have two of them on the
&lt;br&gt;same graph that keep covering one another, it makes it easier for the
&lt;br&gt;eye to pick out the two graphs, as opposed to simply using an alpha,
&lt;br&gt;which gives a solid color that can be mis-interpreted as another
&lt;br&gt;graph.
&lt;br&gt;&lt;br&gt;I also wanted the ability to make it so that peak values could be
&lt;br&gt;highlighted in a different color if desired, as in a cpu graph going
&lt;br&gt;from green through yellow to red.
&lt;br&gt;&lt;br&gt;I haven't thought about making it carry information, although it might
&lt;br&gt;be neat to show temporal distribution of an average value (ie, turn
&lt;br&gt;the dataset on its side, and make it represent color instead of
&lt;br&gt;displacement). I don't really know how to get into that, since all
&lt;br&gt;I've played with so far is the drawing code.
&lt;br&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; can you please also add a patch for the documentation ?
&lt;br&gt;&lt;br&gt;Hopefully the attached patch will suffice.
&lt;br&gt;&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;rian
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26221040&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/patch-to-do-vertical-gradients-tp26220087p26221040.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26220087</id>
	<title>patch to do vertical gradients</title>
	<published>2009-11-05T10:08:39Z</published>
	<updated>2009-11-05T10:08:39Z</updated>
	<author>
		<name>Rian Shelley</name>
	</author>
	<content type="html">Somebody on the irc channel suggested that I post this patch here. The
&lt;br&gt;patch is against rrdtool 1.3.8.
&lt;br&gt;&lt;br&gt;This adds the GRAD element, which acts more or less like an AREA,
&lt;br&gt;except you can specify a second color and a height which is used to
&lt;br&gt;create a gradient from one color to the next.
&lt;br&gt;&lt;br&gt;I also attached an example graph that uses this patch. The gradients
&lt;br&gt;in it are generated with these commands:
&lt;br&gt;&lt;br&gt;GRAD:ips#4444ff:half\\ firewall\\ states
&lt;br&gt;GRAD:Bin#00cc00#0099441f:0:incoming\\ bandwidth
&lt;br&gt;&lt;br&gt;The syntax is
&lt;br&gt;vname-or-value[#color[#color:gradientheight][:legend]][:STACK]
&lt;br&gt;&lt;br&gt;if the second color is missing, it is assumed to be #00000000 and the
&lt;br&gt;gradientheight defaults to 50
&lt;br&gt;&lt;br&gt;gradientheight can actually produce 3 kinds of results depending on its value:
&lt;br&gt;gradientheight &amp;gt; 0
&lt;br&gt;&amp;nbsp; &amp;nbsp; generates a fixed-height gradient from the data point down. (fire style)
&lt;br&gt;gradientheight &amp;lt; 0
&lt;br&gt;&amp;nbsp; &amp;nbsp; generates a fixed-height gradient from the 0 line to the data
&lt;br&gt;point. (fixed style)
&lt;br&gt;gradientheight == 0
&lt;br&gt;&amp;nbsp; &amp;nbsp; generates a gradient that is stretched from the data point to the 0 line.
&lt;br&gt;&amp;nbsp; &amp;nbsp; this is what the example image is using.
&lt;br&gt;&lt;br&gt;I would appreciate any comments or suggestions.
&lt;br&gt;&lt;br&gt;&lt;br&gt;--
&lt;br&gt;rian
&lt;br&gt;&lt;br /&gt;&lt;tt&gt;[grad.patch]&lt;/tt&gt;&lt;br /&gt;&lt;hr align=&quot;left&quot; width=&quot;300&quot; /&gt;&lt;tt&gt;diff -crB rrdtool-1.3.8/src/rrd_gfx.c ../rrdtool-1.3.8/src/rrd_gfx.c
&lt;br&gt;*** rrdtool-1.3.8/src/rrd_gfx.c	Tue May 19 07:45:05 2009
&lt;br&gt;--- ../rrdtool-1.3.8/src/rrd_gfx.c	Thu Nov &amp;nbsp;5 10:17:01 2009
&lt;br&gt;***************
&lt;br&gt;*** 105,110 ****
&lt;br&gt;--- 106,147 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; cairo_line_to(cr, x, y);
&lt;br&gt;&amp;nbsp; }
&lt;br&gt;&amp;nbsp; 
&lt;br&gt;+ /* add a point to a line or to an area */
&lt;br&gt;+ void gfx_add_rect_fadey(
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; image_desc_t *im,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; double x1,double y1,
&lt;br&gt;+ 	double x2,double y2,
&lt;br&gt;+ 	double py,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; gfx_color_t color1,
&lt;br&gt;+ 	gfx_color_t color2,
&lt;br&gt;+ 	double height)
&lt;br&gt;+ {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; cairo_t &amp;nbsp;*cr = im-&amp;gt;cr;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; 
&lt;br&gt;+ 	cairo_new_path(cr);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; gfx_area_fit(im, &amp;x1, &amp;y1);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; gfx_area_fit(im, &amp;x2, &amp;y2);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; cairo_line_to(cr, x1, y1);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; cairo_line_to(cr, x1, y2);
&lt;br&gt;+ 	cairo_line_to(cr, x2, y2);
&lt;br&gt;+ 	cairo_line_to(cr, x2, y1);
&lt;br&gt;+ 	cairo_close_path(cr);
&lt;br&gt;+ 	cairo_pattern_t* p;
&lt;br&gt;+ 	if (height &amp;lt; 0) {
&lt;br&gt;+ 		p = cairo_pattern_create_linear(x1,y1,x2,y1+height);
&lt;br&gt;+ 	} else if (height &amp;gt; 0) {
&lt;br&gt;+ 		p = cairo_pattern_create_linear(x1,(y2+py)/2+height,x2,(y2+py)/2);
&lt;br&gt;+ 	} else {
&lt;br&gt;+ 		p = cairo_pattern_create_linear(x1,y1,x2,(y2+py)/2);
&lt;br&gt;+ 	}
&lt;br&gt;+ 	//cairo_pattern_t* p = cairo_pattern_create_linear(x1,py+50,x2,py);
&lt;br&gt;+ 	cairo_pattern_add_color_stop_rgba(p, 1, color1.red,color1.green,color1.blue,color1.alpha);
&lt;br&gt;+ 	cairo_pattern_add_color_stop_rgba(p, 0, color2.red,color2.green,color2.blue,color2.alpha);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; cairo_set_source(cr, p);
&lt;br&gt;+ 	cairo_pattern_destroy(p);
&lt;br&gt;+ 	cairo_fill(cr);
&lt;br&gt;+ }
&lt;br&gt;+ 
&lt;br&gt;&amp;nbsp; void gfx_close_path(
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; image_desc_t *im)
&lt;br&gt;&amp;nbsp; {
&lt;br&gt;diff -crB rrdtool-1.3.8/src/rrd_graph.c ../rrdtool-1.3.8/src/rrd_graph.c
&lt;br&gt;*** rrdtool-1.3.8/src/rrd_graph.c	Tue May 19 07:45:05 2009
&lt;br&gt;--- ../rrdtool-1.3.8/src/rrd_graph.c	Thu Nov &amp;nbsp;5 10:19:45 2009
&lt;br&gt;***************
&lt;br&gt;*** 227,232 ****
&lt;br&gt;--- 227,233 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; conv_if(VRULE, GF_VRULE);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; conv_if(LINE, GF_LINE);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; conv_if(AREA, GF_AREA);
&lt;br&gt;+ 	conv_if(GRAD, GF_GRAD);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; conv_if(STACK, GF_STACK);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; conv_if(TICK, GF_TICK);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; conv_if(TEXTALIGN, GF_TEXTALIGN);
&lt;br&gt;***************
&lt;br&gt;*** 1176,1182 ****
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; /* memory for the processed data */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; for (i = 0; i &amp;lt; im-&amp;gt;gdes_c; i++) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((im-&amp;gt;gdes[i].gf == GF_LINE) ||
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (im-&amp;gt;gdes[i].gf == GF_AREA) || (im-&amp;gt;gdes[i].gf == GF_TICK)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((im-&amp;gt;gdes[i].p_data = (rrd_value_t*)(malloc((im-&amp;gt;xsize + 1)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* sizeof(rrd_value_t)))) == NULL) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; rrd_set_error(&amp;quot;malloc data_proc&amp;quot;);
&lt;br&gt;--- 1177,1185 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; /* memory for the processed data */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; for (i = 0; i &amp;lt; im-&amp;gt;gdes_c; i++) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((im-&amp;gt;gdes[i].gf == GF_LINE) ||
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (im-&amp;gt;gdes[i].gf == GF_AREA) || 
&lt;br&gt;! 			(im-&amp;gt;gdes[i].gf == GF_GRAD) ||
&lt;br&gt;! 			(im-&amp;gt;gdes[i].gf == GF_TICK)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ((im-&amp;gt;gdes[i].p_data = (rrd_value_t*)(malloc((im-&amp;gt;xsize + 1)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* sizeof(rrd_value_t)))) == NULL) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; rrd_set_error(&amp;quot;malloc data_proc&amp;quot;);
&lt;br&gt;***************
&lt;br&gt;*** 1197,1202 ****
&lt;br&gt;--- 1200,1206 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; switch (im-&amp;gt;gdes[ii].gf) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_LINE:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_AREA:
&lt;br&gt;+ 			case GF_GRAD:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_TICK:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (!im-&amp;gt;gdes[ii].stack)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; paintval = 0.0;
&lt;br&gt;***************
&lt;br&gt;*** 1576,1581 ****
&lt;br&gt;--- 1580,1586 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_LINE:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_AREA:
&lt;br&gt;+ 		case GF_GRAD:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_TICK:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; graphelement = 1;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;***************
&lt;br&gt;*** 3208,3213 ****
&lt;br&gt;--- 3213,3219 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_LINE:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_AREA:
&lt;br&gt;+ 		case GF_GRAD:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* fix data points at oo and -oo */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for (ii = 0; ii &amp;lt; im-&amp;gt;xsize; ii++) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (isinf(im-&amp;gt;gdes[i].p_data[ii])) {
&lt;br&gt;***************
&lt;br&gt;*** 3306,3311 ****
&lt;br&gt;--- 3312,3319 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cairo_stroke(im-&amp;gt;cr);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cairo_restore(im-&amp;gt;cr);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;+ 					double lastx=0;
&lt;br&gt;+ 					double lasty=0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; int &amp;nbsp; &amp;nbsp; &amp;nbsp; idxI = -1;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; double &amp;nbsp; *foreY =
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (double *) malloc(sizeof(double) * im-&amp;gt;xsize * 2);
&lt;br&gt;***************
&lt;br&gt;*** 3336,3347 ****
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;[cntI + 1], 4)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cntI++;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gfx_new_area(im,
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;backX[0], backY[0],
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;foreX[0], foreY[0],
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;foreX[cntI],
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;foreY[cntI], im-&amp;gt;gdes[i].col);
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; while (cntI &amp;lt; idxI) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lastI = cntI;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cntI++;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; while (cntI &amp;lt; idxI
&lt;br&gt;--- 3344,3360 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;[cntI + 1], 4)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cntI++;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;! 							if (im-&amp;gt;gdes[i].gf != GF_GRAD) {
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 	gfx_new_area(im,
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 	 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; backX[0], backY[0],
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 	 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; foreX[0], foreY[0],
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 	 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; foreX[cntI],
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 	 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; foreY[cntI], im-&amp;gt;gdes[i].col);
&lt;br&gt;! 							} else {
&lt;br&gt;! 								lastx = foreX[cntI];
&lt;br&gt;! 								lasty = foreY[cntI];
&lt;br&gt;! 							}
&lt;br&gt;! 							while (cntI &amp;lt; idxI) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lastI = cntI;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cntI++;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; while (cntI &amp;lt; idxI
&lt;br&gt;***************
&lt;br&gt;*** 3357,3365 ****
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + 1], 4)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cntI++;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gfx_add_point(im, foreX[cntI], foreY[cntI]);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gfx_add_point(im, backX[idxI], backY[idxI]);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; while (idxI &amp;gt; 1) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lastI = idxI;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; idxI--;
&lt;br&gt;--- 3370,3401 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; + 1], 4)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cntI++;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;! 								if (im-&amp;gt;gdes[i].gf != GF_GRAD) {
&lt;br&gt;! 	 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;gfx_add_point(im, foreX[cntI], foreY[cntI]);
&lt;br&gt;! 								} else {
&lt;br&gt;! 									gfx_add_rect_fadey(im, 
&lt;br&gt;! 										lastx, foreY[0],
&lt;br&gt;! 										foreX[cntI], foreY[cntI], lasty, 
&lt;br&gt;! 										im-&amp;gt;gdes[i].col,
&lt;br&gt;! 										im-&amp;gt;gdes[i].col2,
&lt;br&gt;! 										im-&amp;gt;gdes[i].gradheight
&lt;br&gt;! 										);
&lt;br&gt;! 									lastx = foreX[cntI];
&lt;br&gt;! 									lasty = foreY[cntI];
&lt;br&gt;! 								}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;! 							if (im-&amp;gt;gdes[i].gf != GF_GRAD) {
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 	gfx_add_point(im, backX[idxI], backY[idxI]);
&lt;br&gt;! 							} else {
&lt;br&gt;! 								gfx_add_rect_fadey(im,
&lt;br&gt;! 									lastx, foreY[0],
&lt;br&gt;! 									backX[idxI], backY[idxI], lasty,
&lt;br&gt;! 									im-&amp;gt;gdes[i].col,
&lt;br&gt;! 									im-&amp;gt;gdes[i].col2,
&lt;br&gt;! 									im-&amp;gt;gdes[i].gradheight);
&lt;br&gt;! 								lastx = backX[idxI];
&lt;br&gt;! 								lasty = backY[idxI];
&lt;br&gt;! 							}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; while (idxI &amp;gt; 1) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lastI = idxI;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; idxI--;
&lt;br&gt;***************
&lt;br&gt;*** 3376,3386 ****
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - 1], 4)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; idxI--;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gfx_add_point(im, backX[idxI], backY[idxI]);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; idxI = -1;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; drawem = 0;
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gfx_close_path(im);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (drawem != 0) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; drawem = 0;
&lt;br&gt;--- 3412,3434 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - 1], 4)) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; idxI--;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;! 								if (im-&amp;gt;gdes[i].gf != GF_GRAD) {
&lt;br&gt;! 	 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;gfx_add_point(im, backX[idxI], backY[idxI]);
&lt;br&gt;! 								} else {
&lt;br&gt;! 									gfx_add_rect_fadey(im,
&lt;br&gt;! 										lastx, foreY[0],
&lt;br&gt;! 										backX[idxI], backY[idxI], lasty,
&lt;br&gt;! 										im-&amp;gt;gdes[i].col,
&lt;br&gt;! 										im-&amp;gt;gdes[i].col2,
&lt;br&gt;! 										im-&amp;gt;gdes[i].gradheight);
&lt;br&gt;! 									lastx = backX[idxI];
&lt;br&gt;! 									lasty = backY[idxI];
&lt;br&gt;! 								}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; idxI = -1;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; drawem = 0;
&lt;br&gt;! 							if (im-&amp;gt;gdes[i].gf != GF_GRAD) 
&lt;br&gt;! 	 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;gfx_close_path(im);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (drawem != 0) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; drawem = 0;
&lt;br&gt;***************
&lt;br&gt;*** 3574,3579 ****
&lt;br&gt;--- 3622,3632 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].col.green = 0.0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].col.blue = 0.0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].col.alpha = 0.0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].col2.red = 0.0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].col2.green = 0.0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].col2.blue = 0.0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].col2.alpha = 0.0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].gradheight = 50.0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].legend[0] = '\0';
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].format[0] = '\0';
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; im-&amp;gt;gdes[im-&amp;gt;gdes_c - 1].strftm = 0;
&lt;br&gt;diff -crB rrdtool-1.3.8/src/rrd_graph.h ../rrdtool-1.3.8/src/rrd_graph.h
&lt;br&gt;*** rrdtool-1.3.8/src/rrd_graph.h	Fri Dec 26 01:05:03 2008
&lt;br&gt;--- ../rrdtool-1.3.8/src/rrd_graph.h	Thu Nov &amp;nbsp;5 10:36:52 2009
&lt;br&gt;***************
&lt;br&gt;*** 51,57 ****
&lt;br&gt;&amp;nbsp; #define GRIDWIDTH &amp;nbsp;0.4
&lt;br&gt;&amp;nbsp; 
&lt;br&gt;&amp;nbsp; enum gf_en { GF_PRINT = 0, GF_GPRINT, GF_COMMENT, GF_HRULE, GF_VRULE, GF_LINE,
&lt;br&gt;! &amp;nbsp; &amp;nbsp; GF_AREA, GF_STACK, GF_TICK, GF_TEXTALIGN,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; GF_DEF, GF_CDEF, GF_VDEF, GF_SHIFT,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; GF_XPORT
&lt;br&gt;&amp;nbsp; };
&lt;br&gt;--- 51,57 ----
&lt;br&gt;&amp;nbsp; #define GRIDWIDTH &amp;nbsp;0.4
&lt;br&gt;&amp;nbsp; 
&lt;br&gt;&amp;nbsp; enum gf_en { GF_PRINT = 0, GF_GPRINT, GF_COMMENT, GF_HRULE, GF_VRULE, GF_LINE,
&lt;br&gt;! &amp;nbsp; &amp;nbsp; GF_AREA,GF_GRAD, GF_STACK, GF_TICK, GF_TEXTALIGN,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; GF_DEF, GF_CDEF, GF_VDEF, GF_SHIFT,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; GF_XPORT
&lt;br&gt;&amp;nbsp; };
&lt;br&gt;***************
&lt;br&gt;*** 156,162 ****
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; long &amp;nbsp; &amp;nbsp; &amp;nbsp;ds; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* data source number */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; enum cf_en cf; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* consolidation function */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; enum cf_en cf_reduce; &amp;nbsp; /* consolidation function for reduce_data() */
&lt;br&gt;! &amp;nbsp; &amp;nbsp; struct gfx_color_t col; /* graph color */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; char &amp;nbsp; &amp;nbsp; &amp;nbsp;format[FMT_LEG_LEN + 5]; &amp;nbsp;/* format for PRINT AND GPRINT */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; char &amp;nbsp; &amp;nbsp; &amp;nbsp;legend[FMT_LEG_LEN + 5]; &amp;nbsp;/* legend */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; int &amp;nbsp; &amp;nbsp; &amp;nbsp; strftm; &amp;nbsp; /* should the VDEF legend be formated with strftime */
&lt;br&gt;--- 156,163 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; long &amp;nbsp; &amp;nbsp; &amp;nbsp;ds; &amp;nbsp; &amp;nbsp; &amp;nbsp; /* data source number */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; enum cf_en cf; &amp;nbsp; &amp;nbsp; &amp;nbsp;/* consolidation function */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; enum cf_en cf_reduce; &amp;nbsp; /* consolidation function for reduce_data() */
&lt;br&gt;! &amp;nbsp; &amp;nbsp; struct gfx_color_t col, col2; /* graph color */
&lt;br&gt;! 	double &amp;nbsp; &amp;nbsp;gradheight;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; char &amp;nbsp; &amp;nbsp; &amp;nbsp;format[FMT_LEG_LEN + 5]; &amp;nbsp;/* format for PRINT AND GPRINT */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; char &amp;nbsp; &amp;nbsp; &amp;nbsp;legend[FMT_LEG_LEN + 5]; &amp;nbsp;/* legend */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; int &amp;nbsp; &amp;nbsp; &amp;nbsp; strftm; &amp;nbsp; /* should the VDEF legend be formated with strftime */
&lt;br&gt;***************
&lt;br&gt;*** 424,429 ****
&lt;br&gt;--- 425,449 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; double x,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; double y);
&lt;br&gt;&amp;nbsp; 
&lt;br&gt;+ /* create a rect that has a gradient from color1 to color2 in height pixels 
&lt;br&gt;+ &amp;nbsp;* height &amp;gt; 0:
&lt;br&gt;+ &amp;nbsp;* 		gradient starts at top and goes down a fixed number of pixels (fire style)
&lt;br&gt;+ &amp;nbsp;* height &amp;lt; 0:
&lt;br&gt;+ &amp;nbsp;* 		gradient starts at bottom and goes up a fixed number of pixels (constant style)
&lt;br&gt;+ &amp;nbsp;* height == 0:
&lt;br&gt;+ &amp;nbsp;* 		gradient is stretched between two points
&lt;br&gt;+ &amp;nbsp;*/
&lt;br&gt;+ void gfx_add_rect_fadey(
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; image_desc_t *im,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; double x1,double y1,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; double x2,double y2,
&lt;br&gt;+ 	double py,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; gfx_color_t color1,
&lt;br&gt;+ 	gfx_color_t color2,
&lt;br&gt;+ 	double height);
&lt;br&gt;+ 				
&lt;br&gt;+ 
&lt;br&gt;+ 
&lt;br&gt;&amp;nbsp; /* close current path so it ends at the same point as it started */
&lt;br&gt;&amp;nbsp; void &amp;nbsp; &amp;nbsp; &amp;nbsp;gfx_close_path(
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; image_desc_t *im);
&lt;br&gt;diff -crB rrdtool-1.3.8/src/rrd_graph_helper.c ../rrdtool-1.3.8/src/rrd_graph_helper.c
&lt;br&gt;*** rrdtool-1.3.8/src/rrd_graph_helper.c	Tue May 19 07:45:05 2009
&lt;br&gt;--- ../rrdtool-1.3.8/src/rrd_graph_helper.c	Thu Nov &amp;nbsp;5 10:38:27 2009
&lt;br&gt;***************
&lt;br&gt;*** 532,538 ****
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; graph_desc_t *const gdp,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; image_desc_t *const im)
&lt;br&gt;&amp;nbsp; {
&lt;br&gt;! &amp;nbsp; &amp;nbsp; int &amp;nbsp; &amp;nbsp; &amp;nbsp; i, j, k;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; int &amp;nbsp; &amp;nbsp; &amp;nbsp; colorfound = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; char &amp;nbsp; &amp;nbsp; &amp;nbsp;tmpstr[MAX_VNAME_LEN + 10]; &amp;nbsp; /* vname#RRGGBBAA\0 */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; static int spacecnt = 0;
&lt;br&gt;--- 532,538 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; graph_desc_t *const gdp,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; image_desc_t *const im)
&lt;br&gt;&amp;nbsp; {
&lt;br&gt;! &amp;nbsp; &amp;nbsp; int &amp;nbsp; &amp;nbsp; &amp;nbsp; i, j, k, j2;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; int &amp;nbsp; &amp;nbsp; &amp;nbsp; colorfound = 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; char &amp;nbsp; &amp;nbsp; &amp;nbsp;tmpstr[MAX_VNAME_LEN + 10]; &amp;nbsp; /* vname#RRGGBBAA\0 */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; static int spacecnt = 0;
&lt;br&gt;***************
&lt;br&gt;*** 567,576 ****
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; rrd_set_error(&amp;quot;Cannot parse line '%s'&amp;quot;, line);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 1;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;! 
&lt;br&gt;! &amp;nbsp; &amp;nbsp; j = i;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; while (j &amp;gt; 0 &amp;&amp; tmpstr[j] != '#')
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; j--;
&lt;br&gt;&amp;nbsp; 
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; if (j) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; tmpstr[j] = '\0';
&lt;br&gt;--- 567,588 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; rrd_set_error(&amp;quot;Cannot parse line '%s'&amp;quot;, line);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return 1;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;! &amp;nbsp; &amp;nbsp; 
&lt;br&gt;! 	j = i;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; while (j &amp;gt; 0 &amp;&amp; tmpstr[j] != '#')
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; j--;
&lt;br&gt;+ 	//see if there is a second color
&lt;br&gt;+ 	j2 = j-1;
&lt;br&gt;+ 	while (j2 &amp;gt; 0 &amp;&amp; tmpstr[j2] != '#')
&lt;br&gt;+ 		j2--;
&lt;br&gt;+ 	if (j &amp;&amp; j2) { &amp;nbsp; //yes, swap j and j2, so that j is first color, j2 is second
&lt;br&gt;+ 		int tmp = j;
&lt;br&gt;+ 		j = j2;
&lt;br&gt;+ 		j2 = tmp;
&lt;br&gt;+ 		tmpstr[j2] = '\0';
&lt;br&gt;+ 	} else {
&lt;br&gt;+ 		j2 = 0;
&lt;br&gt;+ 	}
&lt;br&gt;&amp;nbsp; 
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; if (j) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; tmpstr[j] = '\0';
&lt;br&gt;***************
&lt;br&gt;*** 578,585 ****
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; /* We now have:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* tmpstr[0] &amp;nbsp; &amp;nbsp;containing vname
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* tmpstr[j] &amp;nbsp; &amp;nbsp;if j!=0 then containing color
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp;* i &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;size of vname + color
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* j &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if j!=0 then size of vname
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;&amp;nbsp; 
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; /* Number or vname ?
&lt;br&gt;--- 590,599 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; /* We now have:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* tmpstr[0] &amp;nbsp; &amp;nbsp;containing vname
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* tmpstr[j] &amp;nbsp; &amp;nbsp;if j!=0 then containing color
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp;* tmpstr[j2] &amp;nbsp; if j2!=0 then containing second color
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp;* i &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;size of vname 
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;* j &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if j!=0 then size of vname
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;* j2			if j2!=0 then size of vname + first color
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*/
&lt;br&gt;&amp;nbsp; 
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; /* Number or vname ?
&lt;br&gt;***************
&lt;br&gt;*** 644,649 ****
&lt;br&gt;--- 658,690 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dprintf(&amp;quot;- parsed color %0.0f,%0.0f,%0.0f,%0.0f\n&amp;quot;, gdp-&amp;gt;col.red,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gdp-&amp;gt;col.green, gdp-&amp;gt;col.blue, gdp-&amp;gt;col.alpha);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; colorfound = 1;
&lt;br&gt;+ 		if (j2) { //second color?
&lt;br&gt;+ 			j2++;
&lt;br&gt;+ 			dprintf(&amp;quot;- examining second color '%s'\n&amp;quot;, &amp;tmpstr[j2]);
&lt;br&gt;+ 			//TODO: maybe rrd_parse_color should take a pointer to gdp-&amp;gt;col instead of gdp
&lt;br&gt;+ 			struct gfx_color_t firstcol = gdp-&amp;gt;col;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 	if (rrd_parse_color(&amp;tmpstr[j2], gdp)) {
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 	rrd_set_error(&amp;quot;Could not parse color in '%s'&amp;quot;, &amp;tmpstr[j2]);
&lt;br&gt;+ 	 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 1;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; 	 &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 	dprintf(&amp;quot;- parsed color %0.0f,%0.0f,%0.0f,%0.0f\n&amp;quot;, gdp-&amp;gt;col.red,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 	 &amp;nbsp; &amp;nbsp;gdp-&amp;gt;col.green, gdp-&amp;gt;col.blue, gdp-&amp;gt;col.alpha);
&lt;br&gt;+ 			gdp-&amp;gt;col2 = gdp-&amp;gt;col;
&lt;br&gt;+ 			gdp-&amp;gt;col = firstcol;
&lt;br&gt;+ 			//we now have a mandatory grid height
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; 		(*eaten) += i;
&lt;br&gt;+ 			if (line[*eaten] != '\0') {
&lt;br&gt;+ 				(*eaten)++;
&lt;br&gt;+ 			}
&lt;br&gt;+ 			dprintf(&amp;quot;- examining gradient height\n&amp;quot;);
&lt;br&gt;+ 			i = scan_for_col(&amp;line[*eaten], MAX_VNAME_LEN + 9, tmpstr);
&lt;br&gt;+ 			sscanf(tmpstr, &amp;quot;%lf%n&amp;quot;, &amp;gdp-&amp;gt;gradheight, &amp;j);
&lt;br&gt;+ 			if (i != j) {
&lt;br&gt;+ 				rrd_set_error(&amp;quot;Could not parse gradient height in '%s'&amp;quot;, tmpstr);
&lt;br&gt;+ 				return 1;
&lt;br&gt;+ 			}
&lt;br&gt;+ 			dprintf(&amp;quot;- parsed gradientheight %0.0f\n&amp;quot;, gdp-&amp;gt;gradheight);
&lt;br&gt;+ 		}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dprintf(&amp;quot;- no color present in '%s'\n&amp;quot;, tmpstr);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }
&lt;br&gt;***************
&lt;br&gt;*** 1113,1118 ****
&lt;br&gt;--- 1154,1160 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_HRULE: /* value#color[:legend] */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_LINE: &amp;nbsp;/* vname-or-value[#color[:legend]][:STACK] */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_AREA: &amp;nbsp;/* vname-or-value[#color[:legend]][:STACK] */
&lt;br&gt;+ 		case GF_GRAD: &amp;nbsp;/* vname-or-value[#color[:legend][#color[:gradientheight]]][:STACK] */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_TICK: &amp;nbsp;/* vname#color[:num[:legend]] */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (rrd_parse_PVHLAST(argv[i], &amp;eaten, gdp, im))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;***************
&lt;br&gt;*** 1122,1128 ****
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_STACK: /* vname-or-value[#color[:legend]] */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (rrd_parse_PVHLAST(argv[i], &amp;eaten, gdp, im))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (last_gf == GF_LINE || last_gf == GF_AREA) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gdp-&amp;gt;gf = last_gf;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gdp-&amp;gt;linewidth = last_linewidth;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;--- 1164,1170 ----
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case GF_STACK: /* vname-or-value[#color[:legend]] */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (rrd_parse_PVHLAST(argv[i], &amp;eaten, gdp, im))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return;
&lt;br&gt;! &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (last_gf == GF_LINE || last_gf == GF_AREA || last_gf == GF_GRAD) {
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gdp-&amp;gt;gf = last_gf;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; gdp-&amp;gt;linewidth = last_linewidth;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; } else {
&lt;br&gt;&lt;/tt&gt;&lt;hr align=&quot;left&quot; width=&quot;300&quot; /&gt;&lt;br /&gt; &lt;br /&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26220087&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;&lt;div class=&quot;small&quot;&gt;&lt;br/&gt;&lt;img src=&quot;http://old.nabble.com/images/icon_attachment.gif&quot; &gt; &lt;strong&gt;samplegradientgraph.png&lt;/strong&gt; (98K) &lt;a href=&quot;http://old.nabble.com/attachment/26220087/0/samplegradientgraph.png&quot; target=&quot;_top&quot;&gt;Download Attachment&lt;/a&gt;&lt;/div&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/patch-to-do-vertical-gradients-tp26220087p26220087.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26174134</id>
	<title>Re: Auth in rrdtools 1.5 - library suggestion</title>
	<published>2009-11-02T18:35:45Z</published>
	<updated>2009-11-02T18:35:45Z</updated>
	<author>
		<name>Tobias Oetiker-3</name>
	</author>
	<content type="html">Hi Thomas,
&lt;br&gt;&lt;br&gt;I just had a look at that page and it does indeed sound interesting
&lt;br&gt;...
&lt;br&gt;&lt;br&gt;thanks for the hint
&lt;br&gt;&lt;br&gt;tobi
&lt;br&gt;&lt;br&gt;Yesterday Thomas Guyot-Sionnest wrote:
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; -----BEGIN PGP SIGNED MESSAGE-----
&lt;br&gt;&amp;gt; Hash: SHA1
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Hi,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I've seen in a wiki page that rrdtool may use authentication or
&lt;br&gt;&amp;gt; authorization in the future. I'd like to suggest a possible library for
&lt;br&gt;&amp;gt; this task: NaCl. This is a fairly new library mare with simplicity and
&lt;br&gt;&amp;gt; high speed in mind. The project was started by Daniel J. Berstein (aka.
&lt;br&gt;&amp;gt; djb), a cryptologist very well known for his very secure software
&lt;br&gt;&amp;gt; (djbdns, Qmail...).
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; The NaCL library project page:
&lt;br&gt;&amp;gt; &lt;a href=&quot;http://nacl.cace-project.eu/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://nacl.cace-project.eu/&lt;/a&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; djb's home page:
&lt;br&gt;&amp;gt; &lt;a href=&quot;http://cr.yp.to/djb.html&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://cr.yp.to/djb.html&lt;/a&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I believe this library should seriously be considered as an alternative
&lt;br&gt;&amp;gt; to TLS (openssl, gnutls) or other libraries for both its speed and security.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Thank you
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; - --
&lt;br&gt;&amp;gt; Thomas
&lt;br&gt;&amp;gt; -----BEGIN PGP SIGNATURE-----
&lt;br&gt;&amp;gt; Version: GnuPG v1.4.9 (MingW32)
&lt;br&gt;&amp;gt; Comment: Using GnuPG with Mozilla - &lt;a href=&quot;http://enigmail.mozdev.org/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://enigmail.mozdev.org/&lt;/a&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; iEYEARECAAYFAkrvEHcACgkQ6dZ+Kt5BchZS2wCgjqaLOSpwMNBJZ4qtq8V9/m0a
&lt;br&gt;&amp;gt; Az4An0445M1oIbJNQvl1ktg74JmCQ4HT
&lt;br&gt;&amp;gt; =v8Qf
&lt;br&gt;&amp;gt; -----END PGP SIGNATURE-----
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;/div&gt;&lt;br&gt;-- 
&lt;br&gt;Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
&lt;br&gt;&lt;a href=&quot;http://it.oetiker.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://it.oetiker.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26174134&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tobi@...&lt;/a&gt; ++41 62 775 9902 / sb: -9900
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26174134&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-Auth-in-rrdtools-1.5---library-suggestion-tp26174134p26174134.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26145545</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-31T13:14:19Z</published>
	<updated>2009-10-31T13:14:19Z</updated>
	<author>
		<name>kevin brintnall</name>
	</author>
	<content type="html">&amp;gt; It's pretty clear that the performance when operating in memory is very 
&lt;br&gt;&amp;gt; nice and smooth, but when memory is exceeded things become bumpy. It 
&lt;br&gt;&amp;gt; degrades nicely and recovers well: I saw 9k queue items at one point and 
&lt;br&gt;&amp;gt; that got worked off over close to an hour but did work itself out as 
&lt;br&gt;&amp;gt; opposed to spinning out of control.
&lt;br&gt;&lt;br&gt;9k/hour seems awfully slow. &amp;nbsp;Even my old development box can flush
&lt;br&gt;55k/hour. &amp;nbsp;Maybe more entries are being enqueued at the same time...
&lt;br&gt;&lt;br&gt;&amp;gt; What value of -m do you suggest? -w divided by step size?
&lt;br&gt;&lt;br&gt;That's the maximum; any more than that is just waste. &amp;nbsp;IIRC you had around
&lt;br&gt;~400 cached values per RRD file. &amp;nbsp;So, if you use '-m 400' you'll only have
&lt;br&gt;call realloc() one time. &amp;nbsp;However, the 401st value will cause a large
&lt;br&gt;realloc()...
&lt;br&gt;&lt;br&gt;The ideal value is highly dependent on your malloc() implementation.. &amp;nbsp;I
&lt;br&gt;would start with a power of two large enough to get you relatively few
&lt;br&gt;realloc() but small enough that you don't waste too much... &amp;nbsp;In your case,
&lt;br&gt;maybe '-m 64'.
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;&amp;nbsp;kevin brintnall =~ /&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26145545&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;kbrint@...&lt;/a&gt;/
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26145545&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26145545.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26145127</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-31T12:12:31Z</published>
	<updated>2009-10-31T12:12:31Z</updated>
	<author>
		<name>Thorsten von Eicken</name>
	</author>
	<content type="html">kevin brintnall wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; On Sat, Oct 31, 2009 at 09:52:15AM -0700, Thorsten von Eicken wrote:
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;br&gt;&amp;gt;&amp;gt; Quick follow-up. I decided to add another 3k updates per second (extra 
&lt;br&gt;&amp;gt;&amp;gt; 30k tree nodes) to my test run. See results in
&lt;br&gt;&amp;gt;&amp;gt; &lt;a href=&quot;http://www.voneicken.com/dl/rrd/rrdcached-7.png&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.voneicken.com/dl/rrd/rrdcached-7.png&lt;/a&gt;&lt;br&gt;&amp;gt;&amp;gt; What's interesting is that the server got somewhat overloaded sitting a 
&lt;br&gt;&amp;gt;&amp;gt; lot in I/O wait. By and large the flush queue length remained under 
&lt;br&gt;&amp;gt;&amp;gt; control, except when doing backups (10pm, 8:30am). Memory usage by 
&lt;br&gt;&amp;gt;&amp;gt; rrdcached and collectd remained under control, but there is a long term 
&lt;br&gt;&amp;gt;&amp;gt; upward-trending slope to rrdcached's memory usage which is not good. 
&lt;br&gt;&amp;gt;&amp;gt; Possibly related to the power-of-two allocator patch that Florian 
&lt;br&gt;&amp;gt;&amp;gt; provided. The graph I find the most interesting one is the disk sdk disk 
&lt;br&gt;&amp;gt;&amp;gt; ops (3rd from the end). Before adding the last chunk of traffic the disk 
&lt;br&gt;&amp;gt;&amp;gt; load was write-dominated, which means that rrds were mostly cached in 
&lt;br&gt;&amp;gt;&amp;gt; memory (5-6 GB left after the processes). After adding the extra load 
&lt;br&gt;&amp;gt;&amp;gt; the disk load became read-dominated indicating that the rrd working set 
&lt;br&gt;&amp;gt;&amp;gt; exceeded memory.
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Thorsten,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; If you're becoming read dominated, you should consider lowering your file
&lt;br&gt;&amp;gt; update/sec rate by increasing your -w/-f timers. &amp;nbsp;This just trades one
&lt;br&gt;&amp;gt; kind of cache memory (f/s blocks) for another (update strings).
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;/div&gt;Yeah, but given that I'm already using 1 hour of caching it starts 
&lt;br&gt;getting a bit uncomfortable. I haven't re-tested the journal reading 
&lt;br&gt;yet, but at some point restarting rrdcached becomes really difficult. 
&lt;br&gt;But regardless, I suspect there are 3 performance regimes:
&lt;br&gt;&amp;nbsp;- working set much smaller than memory - cpu scales linearly/smoothly 
&lt;br&gt;with update rate
&lt;br&gt;&amp;nbsp;- working set much larger than memory - it's all about random small 
&lt;br&gt;disk I/O throughput
&lt;br&gt;&amp;nbsp;- working set similar to memory - relatively sharp (?) transition from 
&lt;br&gt;cpu/memory speed to disk speed
&lt;br&gt;It's pretty clear that the performance when operating in memory is very 
&lt;br&gt;nice and smooth, but when memory is exceeded things become bumpy. It 
&lt;br&gt;degrades nicely and recovers well: I saw 9k queue items at one point and 
&lt;br&gt;that got worked off over close to an hour but did work itself out as 
&lt;br&gt;opposed to spinning out of control. But it doesn't look like a safe 
&lt;br&gt;operating regime. So basically gotta keep the rrd working set in memory.
&lt;br&gt;&lt;br&gt;&amp;gt; I'm sending a linear chunk allocator along for allocating
&lt;br&gt;&amp;gt; cache_item_t.values in operator-defined block sizes.. &amp;nbsp;I'd appreciate if
&lt;br&gt;&amp;gt; you'd test it with your load to see if it reduces your CPU usage related
&lt;br&gt;&amp;gt; to frequent realloc().
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;br&gt;What value of -m do you suggest? -w divided by step size?
&lt;br&gt;&lt;br&gt;Thanks,
&lt;br&gt;Thorsten
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26145127&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26145127.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26144945</id>
	<title>[PATCH 2/2] Introduce &quot;-m&quot; argument to reduce calls to realloc().</title>
	<published>2009-10-31T11:46:19Z</published>
	<updated>2009-10-31T11:46:19Z</updated>
	<author>
		<name>kevin brintnall</name>
	</author>
	<content type="html">---
&lt;br&gt;&amp;nbsp;doc/rrdcached.pod | &amp;nbsp; &amp;nbsp;9 +++++++++
&lt;br&gt;&amp;nbsp;src/rrd_daemon.c &amp;nbsp;| &amp;nbsp; 23 ++++++++++++++++++++---
&lt;br&gt;&amp;nbsp;2 files changed, 29 insertions(+), 3 deletions(-)
&lt;br&gt;&lt;br&gt;diff --git a/doc/rrdcached.pod b/doc/rrdcached.pod
&lt;br&gt;index 043e020..5e8728f 100644
&lt;br&gt;--- a/doc/rrdcached.pod
&lt;br&gt;+++ b/doc/rrdcached.pod
&lt;br&gt;@@ -18,6 +18,7 @@ B&amp;lt;rrdcached&amp;gt;
&lt;br&gt;&amp;nbsp;[-F]
&lt;br&gt;&amp;nbsp;[-g]
&lt;br&gt;&amp;nbsp;[B&amp;lt;-b&amp;gt;E&amp;lt;nbsp&amp;gt;I&amp;lt;base_dir&amp;gt;E&amp;lt;nbsp&amp;gt;[B&amp;lt;-B&amp;gt;]]
&lt;br&gt;+[B&amp;lt;-m&amp;gt;E&amp;lt;nbsp&amp;gt;I&amp;lt;alloc_size&amp;gt;]
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;=head1 DESCRIPTION
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -197,6 +198,14 @@ Only permit writes into the base directory specified in B&amp;lt;-b&amp;gt; (and any
&lt;br&gt;&amp;nbsp;sub-directories). &amp;nbsp;This does B&amp;lt;NOT&amp;gt; detect symbolic links. &amp;nbsp;Paths
&lt;br&gt;&amp;nbsp;containing C&amp;lt;../&amp;gt; will also be blocked.
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+=item B&amp;lt;-m&amp;gt; I&amp;lt;alloc_size&amp;gt;
&lt;br&gt;+
&lt;br&gt;+Allocate value pointers in chunks of I&amp;lt;alloc_size&amp;gt;. &amp;nbsp;This may improve CPU
&lt;br&gt;+utilization on machines with slow C&amp;lt;realloc()&amp;gt; implementations, in
&lt;br&gt;+exchange for slightly higher memory utilization. &amp;nbsp;The default isE&amp;lt;nbsp&amp;gt;1.
&lt;br&gt;+Do not set this more than the B&amp;lt;-w&amp;gt; value divided by your average RRD step
&lt;br&gt;+size.
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;=back
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;=head1 AFFECTED RRDTOOL COMMANDS
&lt;br&gt;diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c
&lt;br&gt;index 4c84f19..79ea17b 100644
&lt;br&gt;--- a/src/rrd_daemon.c
&lt;br&gt;+++ b/src/rrd_daemon.c
&lt;br&gt;@@ -174,7 +174,8 @@ struct cache_item_s
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp;char *file;
&lt;br&gt;&amp;nbsp; &amp;nbsp;char **values;
&lt;br&gt;- &amp;nbsp;size_t values_num;
&lt;br&gt;+ &amp;nbsp;size_t values_num;		/* number of valid pointers */
&lt;br&gt;+ &amp;nbsp;size_t values_alloc;		/* number of allocated pointers */
&lt;br&gt;&amp;nbsp; &amp;nbsp;time_t last_flush_time;
&lt;br&gt;&amp;nbsp; &amp;nbsp;time_t last_update_stamp;
&lt;br&gt;&amp;nbsp;#define CI_FLAGS_IN_TREE &amp;nbsp;(1&amp;lt;&amp;lt;0)
&lt;br&gt;@@ -251,6 +252,7 @@ static char *config_pid_file = NULL;
&lt;br&gt;&amp;nbsp;static char *config_base_dir = NULL;
&lt;br&gt;&amp;nbsp;static size_t _config_base_dir_len = 0;
&lt;br&gt;&amp;nbsp;static int config_write_base_only = 0;
&lt;br&gt;+static size_t config_alloc_chunk = 1;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;static listen_socket_t **config_listen_address_list = NULL;
&lt;br&gt;&amp;nbsp;static size_t config_listen_address_list_len = 0;
&lt;br&gt;@@ -638,6 +640,7 @@ static void wipe_ci_values(cache_item_t *ci, time_t when)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp;ci-&amp;gt;values = NULL;
&lt;br&gt;&amp;nbsp; &amp;nbsp;ci-&amp;gt;values_num = 0;
&lt;br&gt;+ &amp;nbsp;ci-&amp;gt;values_alloc = 0;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;ci-&amp;gt;last_flush_time = when;
&lt;br&gt;&amp;nbsp; &amp;nbsp;if (config_write_jitter &amp;gt; 0)
&lt;br&gt;@@ -1434,7 +1437,8 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;else
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ci-&amp;gt;last_update_stamp = stamp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp;if (!rrd_add_strdup(&amp;ci-&amp;gt;values, &amp;ci-&amp;gt;values_num, value))
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;if (!rrd_add_strdup_chunk(&amp;ci-&amp;gt;values, &amp;ci-&amp;gt;values_num, value,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;ci-&amp;gt;values_alloc, config_alloc_chunk))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;RRDD_LOG (LOG_ERR, &amp;quot;handle_request_update: rrd_add_strdup failed.&amp;quot;);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;
&lt;br&gt;@@ -2746,7 +2750,7 @@ static int read_options (int argc, char **argv) /* {{{ */
&lt;br&gt;&amp;nbsp; &amp;nbsp;char **permissions = NULL;
&lt;br&gt;&amp;nbsp; &amp;nbsp;size_t permissions_len = 0;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp;while ((option = getopt(argc, argv, &amp;quot;gl:P:f:w:z:t:Bb:p:Fj:h?&amp;quot;)) != -1)
&lt;br&gt;+ &amp;nbsp;while ((option = getopt(argc, argv, &amp;quot;gl:P:f:w:z:t:Bb:p:Fj:m:h?&amp;quot;)) != -1)
&lt;br&gt;&amp;nbsp; &amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;switch (option)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;{
&lt;br&gt;@@ -3003,6 +3007,19 @@ static int read_options (int argc, char **argv) /* {{{ */
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;break;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;case 'm':
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;int temp = atoi(optarg);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (temp &amp;gt; 0)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;config_alloc_chunk = temp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;fprintf(stderr, &amp;quot;Invalid allocation size: %s\n&amp;quot;, optarg);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;status = 10;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;break;
&lt;br&gt;+
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case 'h':
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;case '?':
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;printf (&amp;quot;RRDCacheD %s\n&amp;quot;
&lt;br&gt;-- 
&lt;br&gt;1.6.4
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26144945&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH-1-2--Add-utility-functions-to-allocate-pointers-in-variable-size-chunks.-tp26144946p26144945.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26144946</id>
	<title>[PATCH 1/2] Add utility functions to allocate pointers in variable size chunks.</title>
	<published>2009-10-31T11:46:18Z</published>
	<updated>2009-10-31T11:46:18Z</updated>
	<author>
		<name>kevin brintnall</name>
	</author>
	<content type="html">---
&lt;br&gt;&amp;nbsp;doc/librrd.pod &amp;nbsp;| &amp;nbsp; 18 ++++++++++++++++++
&lt;br&gt;&amp;nbsp;src/rrd.h &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp; &amp;nbsp;4 ++++
&lt;br&gt;&amp;nbsp;src/rrd_utils.c | &amp;nbsp; 53 ++++++++++++++++++++++++++++++++++++++++++-----------
&lt;br&gt;&amp;nbsp;3 files changed, 64 insertions(+), 11 deletions(-)
&lt;br&gt;&lt;br&gt;diff --git a/doc/librrd.pod b/doc/librrd.pod
&lt;br&gt;index 038746c..396e50c 100644
&lt;br&gt;--- a/doc/librrd.pod
&lt;br&gt;+++ b/doc/librrd.pod
&lt;br&gt;@@ -81,6 +81,16 @@ end of the new C&amp;lt;dest&amp;gt;. &amp;nbsp;Returns 1 on success, 0 on failure.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (!rrd_add_ptr(&amp;arr, &amp;arr_size, elem))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;handle_failure();
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+=item B&amp;lt;rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src, size_t *alloc, size_t chunk)&amp;gt;
&lt;br&gt;+
&lt;br&gt;+Like C&amp;lt;rrd_add_ptr&amp;gt;, except the destination is allocated in chunks of
&lt;br&gt;+C&amp;lt;chunk&amp;gt;. &amp;nbsp;C&amp;lt;alloc&amp;gt; points to the number of entries allocated, whereas
&lt;br&gt;+C&amp;lt;dest_size&amp;gt; points to the number of valid pointers. &amp;nbsp;If more pointers are
&lt;br&gt;+needed, C&amp;lt;chunk&amp;gt; pointers are allocated and C&amp;lt;alloc&amp;gt; is increased
&lt;br&gt;+accordingly. &amp;nbsp;C&amp;lt;alloc&amp;gt; must be E&amp;lt;gt&amp;gt;= C&amp;lt;dest_size&amp;gt;.
&lt;br&gt;+
&lt;br&gt;+This method improves performance on hosts with expensive C&amp;lt;realloc()&amp;gt;.
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;=item B&amp;lt;rrd_add_strdup(char ***dest, size_t *dest_size, char *src)&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;Like C&amp;lt;rrd_add_ptr&amp;gt;, except adds a C&amp;lt;strdup&amp;gt; of the source string.
&lt;br&gt;@@ -91,6 +101,14 @@ Like C&amp;lt;rrd_add_ptr&amp;gt;, except adds a C&amp;lt;strdup&amp;gt; of the source string.
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (!rrd_add_strdup(&amp;arr, &amp;arr_size, str))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;handle_failure();
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+=item B&amp;lt;rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src, size_t *alloc, size_t chunk)&amp;gt;
&lt;br&gt;+
&lt;br&gt;+Like C&amp;lt;rrd_add_strdup&amp;gt;, except the destination is allocated in chunks of
&lt;br&gt;+C&amp;lt;chunk&amp;gt;. &amp;nbsp;C&amp;lt;alloc&amp;gt; points to the number of entries allocated, whereas
&lt;br&gt;+C&amp;lt;dest_size&amp;gt; points to the number of valid pointers. &amp;nbsp;If more pointers are
&lt;br&gt;+needed, C&amp;lt;chunk&amp;gt; pointers are allocated and C&amp;lt;alloc&amp;gt; is increased
&lt;br&gt;+accordingly. &amp;nbsp;C&amp;lt;alloc&amp;gt; must be E&amp;lt;gt&amp;gt;= C&amp;lt;dest_size&amp;gt;.
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;=item B&amp;lt;rrd_free_ptrs(void ***src, size_t *cnt)&amp;gt;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;Free an array of pointers allocated by C&amp;lt;rrd_add_ptr&amp;gt; or
&lt;br&gt;diff --git a/src/rrd.h b/src/rrd.h
&lt;br&gt;index ce7e749..6008794 100644
&lt;br&gt;--- a/src/rrd.h
&lt;br&gt;+++ b/src/rrd.h
&lt;br&gt;@@ -333,8 +333,12 @@ int &amp;nbsp; &amp;nbsp; &amp;nbsp; rrd_proc_start_end(
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;long rrd_random(void);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;size_t *alloc, size_t chunk);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;int rrd_add_ptr(void ***dest, size_t *dest_size, void *src);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;int rrd_add_strdup(char ***dest, size_t *dest_size, char *src);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t *alloc, size_t chunk);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;void rrd_free_ptrs(void ***src, size_t *cnt);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;int rrd_mkdir_p(const char *pathname, mode_t mode);
&lt;br&gt;diff --git a/src/rrd_utils.c b/src/rrd_utils.c
&lt;br&gt;index 3936cff..6853c66 100644
&lt;br&gt;--- a/src/rrd_utils.c
&lt;br&gt;+++ b/src/rrd_utils.c
&lt;br&gt;@@ -50,29 +50,53 @@ long rrd_random(void)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return random();
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
&lt;br&gt;- * realloc as necessary. &amp;nbsp;returns 1 on success, 0 on failure.
&lt;br&gt;+/* rrd_add_ptr_chunk: add a pointer to a dynamically sized array of
&lt;br&gt;+ * pointers, realloc as necessary in multiples of &amp;quot;chunk&amp;quot;.
&lt;br&gt;+ *
&lt;br&gt;+ * &amp;quot;alloc&amp;quot; is the number of pointers allocated
&lt;br&gt;+ * &amp;quot;dest_size&amp;quot; is the number of valid pointers
&lt;br&gt;+ *
&lt;br&gt;+ * returns 1 on success, 0 on failure.
&lt;br&gt;&amp;nbsp; */
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
&lt;br&gt;+int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;size_t *alloc, size_t chunk)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;void **temp;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;assert(dest != NULL);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;assert(alloc != NULL);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;assert(*alloc &amp;gt;= *dest_size);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp;temp = (void **) rrd_realloc(*dest, (*dest_size+1) * sizeof(*dest));
&lt;br&gt;- &amp;nbsp; &amp;nbsp;if (!temp)
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;if (*alloc == *dest_size)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;temp = (void **) rrd_realloc(*dest, (*alloc+chunk) * sizeof(*dest));
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (!temp)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp;*dest = temp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp;temp[*dest_size] = src;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*dest = temp;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;*alloc += chunk;
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;}
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;(*dest)[*dest_size] = src;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;(*dest_size)++;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return 1;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-/* like rrd_add_ptr, but calls strdup() on a string first. */
&lt;br&gt;-int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
&lt;br&gt;+/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
&lt;br&gt;+ * realloc as necessary. &amp;nbsp;returns 1 on success, 0 on failure.
&lt;br&gt;+ */
&lt;br&gt;+int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;size_t alloc = *dest_size;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;return rrd_add_ptr_chunk(dest, dest_size, src, &amp;alloc, 1);
&lt;br&gt;+}
&lt;br&gt;+
&lt;br&gt;+/* like rrd_add_ptr_chunk, but calls strdup() on a string first. */
&lt;br&gt;+int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src,
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; size_t *alloc, size_t chunk)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;char *dup_src;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;int add_ok;
&lt;br&gt;@@ -84,13 +108,20 @@ int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (!dup_src)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return 0;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp; &amp;nbsp;add_ok = rrd_add_ptr((void ***)dest, dest_size, (void *)dup_src);
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;add_ok = rrd_add_ptr_chunk((void ***)dest, dest_size, (void *)dup_src, alloc, chunk);
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;if (!add_ok)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;free(dup_src);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return add_ok;
&lt;br&gt;&amp;nbsp;}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;+int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
&lt;br&gt;+{
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;size_t alloc = *dest_size;
&lt;br&gt;+
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;return rrd_add_strdup_chunk(dest, dest_size, src, &amp;alloc, 1);
&lt;br&gt;+}
&lt;br&gt;+
&lt;br&gt;&amp;nbsp;void rrd_free_ptrs(void ***src, size_t *cnt)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;void **sp;
&lt;br&gt;-- 
&lt;br&gt;1.6.4
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26144946&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH-1-2--Add-utility-functions-to-allocate-pointers-in-variable-size-chunks.-tp26144946p26144946.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26144924</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-31T11:42:53Z</published>
	<updated>2009-10-31T11:42:53Z</updated>
	<author>
		<name>kevin brintnall</name>
	</author>
	<content type="html">On Sat, Oct 31, 2009 at 09:52:15AM -0700, Thorsten von Eicken wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Quick follow-up. I decided to add another 3k updates per second (extra 
&lt;br&gt;&amp;gt; 30k tree nodes) to my test run. See results in
&lt;br&gt;&amp;gt; &lt;a href=&quot;http://www.voneicken.com/dl/rrd/rrdcached-7.png&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.voneicken.com/dl/rrd/rrdcached-7.png&lt;/a&gt;&lt;br&gt;&amp;gt; What's interesting is that the server got somewhat overloaded sitting a 
&lt;br&gt;&amp;gt; lot in I/O wait. By and large the flush queue length remained under 
&lt;br&gt;&amp;gt; control, except when doing backups (10pm, 8:30am). Memory usage by 
&lt;br&gt;&amp;gt; rrdcached and collectd remained under control, but there is a long term 
&lt;br&gt;&amp;gt; upward-trending slope to rrdcached's memory usage which is not good. 
&lt;br&gt;&amp;gt; Possibly related to the power-of-two allocator patch that Florian 
&lt;br&gt;&amp;gt; provided. The graph I find the most interesting one is the disk sdk disk 
&lt;br&gt;&amp;gt; ops (3rd from the end). Before adding the last chunk of traffic the disk 
&lt;br&gt;&amp;gt; load was write-dominated, which means that rrds were mostly cached in 
&lt;br&gt;&amp;gt; memory (5-6 GB left after the processes). After adding the extra load 
&lt;br&gt;&amp;gt; the disk load became read-dominated indicating that the rrd working set 
&lt;br&gt;&amp;gt; exceeded memory.
&lt;/div&gt;&lt;br&gt;Thorsten,
&lt;br&gt;&lt;br&gt;If you're becoming read dominated, you should consider lowering your file
&lt;br&gt;update/sec rate by increasing your -w/-f timers. &amp;nbsp;This just trades one
&lt;br&gt;kind of cache memory (f/s blocks) for another (update strings).
&lt;br&gt;&lt;br&gt;I'm sending a linear chunk allocator along for allocating
&lt;br&gt;cache_item_t.values in operator-defined block sizes.. &amp;nbsp;I'd appreciate if
&lt;br&gt;you'd test it with your load to see if it reduces your CPU usage related
&lt;br&gt;to frequent realloc().
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;&amp;nbsp;kevin brintnall =~ /&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26144924&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;kbrint@...&lt;/a&gt;/
&lt;br&gt;&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Thorsten
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Thorsten von Eicken wrote:
&lt;br&gt;&amp;gt; &amp;gt; Thorsten von Eicken wrote:
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; 
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; 37.1 % of the time it spent in ?handle_request_update? the daemon is
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; actually waiting for ?realloc?. This is (to me) very unexpected and a
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; schoolbook example of ?measure before you optimize?.
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; I think we can get rid of this bottleneck by writing a specialized
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; version of ?rrd_add_strdup? which reallocates powers of ten. Something
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; like:
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; [...]
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; It'd be great if you could give the attached patch a try
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; spends all of its time (more than 99 %) in ?realloc?. So in consequence
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; Test is running, including Kevin's simplification... Thanks for the 
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; help!!!
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;gt; &amp;gt; Things are again looking much better, almost great I should say! The one 
&lt;br&gt;&amp;gt; &amp;gt; thing that still makes me a bit uncomfortable is that at the end of the 
&lt;br&gt;&amp;gt; &amp;gt; second hour of run-time there was a cpu spike which caused collectd to 
&lt;br&gt;&amp;gt; &amp;gt; grow rapidly. (Still using -w 3600 -z 3600 -f 7200, I put a load of ~50k 
&lt;br&gt;&amp;gt; &amp;gt; tree nodes right from the start.) You can see the graphs at 
&lt;br&gt;&amp;gt; &amp;gt; &lt;a href=&quot;http://www.voneicken.com/dl/rrd/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.voneicken.com/dl/rrd/&lt;/a&gt;&amp;nbsp;look for the rrdcached-6* series. It 
&lt;br&gt;&amp;gt; &amp;gt; flattens out nicely after the spike, but it's one of those things that 
&lt;br&gt;&amp;gt; &amp;gt; tend to bite sooner or later. I'm not sure what to do about it.
&lt;br&gt;&amp;gt; &amp;gt; Thorsten
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; _______________________________________________
&lt;br&gt;&amp;gt; &amp;gt; rrd-developers mailing list
&lt;br&gt;&amp;gt; &amp;gt; &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26144924&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&amp;gt; &amp;gt; &lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; 
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; _______________________________________________
&lt;br&gt;&amp;gt; rrd-developers mailing list
&lt;br&gt;&amp;gt; &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26144924&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&amp;gt; &lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;/div&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26144924&amp;i=3&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26144924.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26144037</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-31T09:52:15Z</published>
	<updated>2009-10-31T09:52:15Z</updated>
	<author>
		<name>Thorsten von Eicken</name>
	</author>
	<content type="html">Quick follow-up. I decided to add another 3k updates per second (extra 
&lt;br&gt;30k tree nodes) to my test run. See results in
&lt;br&gt;&lt;a href=&quot;http://www.voneicken.com/dl/rrd/rrdcached-7.png&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.voneicken.com/dl/rrd/rrdcached-7.png&lt;/a&gt;&lt;br&gt;What's interesting is that the server got somewhat overloaded sitting a 
&lt;br&gt;lot in I/O wait. By and large the flush queue length remained under 
&lt;br&gt;control, except when doing backups (10pm, 8:30am). Memory usage by 
&lt;br&gt;rrdcached and collectd remained under control, but there is a long term 
&lt;br&gt;upward-trending slope to rrdcached's memory usage which is not good. 
&lt;br&gt;Possibly related to the power-of-two allocator patch that Florian 
&lt;br&gt;provided. The graph I find the most interesting one is the disk sdk disk 
&lt;br&gt;ops (3rd from the end). Before adding the last chunk of traffic the disk 
&lt;br&gt;load was write-dominated, which means that rrds were mostly cached in 
&lt;br&gt;memory (5-6 GB left after the processes). After adding the extra load 
&lt;br&gt;the disk load became read-dominated indicating that the rrd working set 
&lt;br&gt;exceeded memory.
&lt;br&gt;&lt;br&gt;Thorsten
&lt;br&gt;&lt;br&gt;&lt;br&gt;Thorsten von Eicken wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Thorsten von Eicken wrote:
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; 37.1 % of the time it spent in “handle_request_update” the daemon is
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; actually waiting for “realloc”. This is (to me) very unexpected and a
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; schoolbook example of “measure before you optimize”.
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; I think we can get rid of this bottleneck by writing a specialized
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; version of “rrd_add_strdup” which reallocates powers of ten. Something
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; like:
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; [...]
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; It'd be great if you could give the attached patch a try
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;gt;&amp;gt; spends all of its time (more than 99 %) in “realloc”. So in consequence
&lt;br&gt;&amp;gt;&amp;gt; Test is running, including Kevin's simplification... Thanks for the 
&lt;br&gt;&amp;gt;&amp;gt; help!!!
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;gt; Things are again looking much better, almost great I should say! The one 
&lt;br&gt;&amp;gt; thing that still makes me a bit uncomfortable is that at the end of the 
&lt;br&gt;&amp;gt; second hour of run-time there was a cpu spike which caused collectd to 
&lt;br&gt;&amp;gt; grow rapidly. (Still using -w 3600 -z 3600 -f 7200, I put a load of ~50k 
&lt;br&gt;&amp;gt; tree nodes right from the start.) You can see the graphs at 
&lt;br&gt;&amp;gt; &lt;a href=&quot;http://www.voneicken.com/dl/rrd/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.voneicken.com/dl/rrd/&lt;/a&gt;&amp;nbsp;look for the rrdcached-6* series. It 
&lt;br&gt;&amp;gt; flattens out nicely after the spike, but it's one of those things that 
&lt;br&gt;&amp;gt; tend to bite sooner or later. I'm not sure what to do about it.
&lt;br&gt;&amp;gt; Thorsten
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; _______________________________________________
&lt;br&gt;&amp;gt; rrd-developers mailing list
&lt;br&gt;&amp;gt; &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26144037&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&amp;gt; &lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;/div&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26144037&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26144037.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26137981</id>
	<title>Re: [PATCH] JOURNAL_REPLAY macro clarifies our intentions</title>
	<published>2009-10-30T15:50:26Z</published>
	<updated>2009-10-30T15:50:26Z</updated>
	<author>
		<name>Tobias Oetiker-3</name>
	</author>
	<content type="html">Hi Kevin,
&lt;br&gt;Today kevin brintnall wrote:
&lt;br&gt;&lt;br&gt;&amp;gt; ---
&lt;br&gt;&amp;gt; &amp;nbsp;src/rrd_daemon.c | &amp;nbsp; 18 +++++++++---------
&lt;br&gt;&amp;gt; &amp;nbsp;1 files changed, 9 insertions(+), 9 deletions(-)
&lt;br&gt;&lt;br&gt;it's getting better all the time ...
&lt;br&gt;&lt;br&gt;cheers
&lt;br&gt;tobi
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
&lt;br&gt;&lt;a href=&quot;http://it.oetiker.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://it.oetiker.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26137981&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tobi@...&lt;/a&gt; ++41 62 775 9902 / sb: -9900
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26137981&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--JOURNAL_REPLAY-macro-clarifies-our-intentions-tp26135576p26137981.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26135576</id>
	<title>[PATCH] JOURNAL_REPLAY macro clarifies our intentions</title>
	<published>2009-10-30T12:17:33Z</published>
	<updated>2009-10-30T12:17:33Z</updated>
	<author>
		<name>kevin brintnall</name>
	</author>
	<content type="html">---
&lt;br&gt;&amp;nbsp;src/rrd_daemon.c | &amp;nbsp; 18 +++++++++---------
&lt;br&gt;&amp;nbsp;1 files changed, 9 insertions(+), 9 deletions(-)
&lt;br&gt;&lt;br&gt;diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c
&lt;br&gt;index 1946003..4c84f19 100644
&lt;br&gt;--- a/src/rrd_daemon.c
&lt;br&gt;+++ b/src/rrd_daemon.c
&lt;br&gt;@@ -265,6 +265,7 @@ static uint64_t stats_journal_rotate = 0;
&lt;br&gt;&amp;nbsp;static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp;/* Journaled updates */
&lt;br&gt;+#define JOURNAL_REPLAY(s) ((s) == NULL)
&lt;br&gt;&amp;nbsp;#define JOURNAL_BASE &amp;quot;rrd.journal&amp;quot;
&lt;br&gt;&amp;nbsp;static journal_set *journal_cur = NULL;
&lt;br&gt;&amp;nbsp;static journal_set *journal_old = NULL;
&lt;br&gt;@@ -528,7 +529,7 @@ static int add_response_info(listen_socket_t *sock, char *fmt, ...) /* {{{ */
&lt;br&gt;&amp;nbsp; &amp;nbsp;char buffer[CMD_MAX];
&lt;br&gt;&amp;nbsp; &amp;nbsp;int len;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp;if (sock == NULL) return 0; /* journal replay mode */
&lt;br&gt;+ &amp;nbsp;if (JOURNAL_REPLAY(sock)) return 0;
&lt;br&gt;&amp;nbsp; &amp;nbsp;if (sock-&amp;gt;batch_start) return 0; /* no extra info returned when in BATCH */
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;va_start(argp, fmt);
&lt;br&gt;@@ -575,7 +576,7 @@ static int send_response (listen_socket_t *sock, response_code rc,
&lt;br&gt;&amp;nbsp; &amp;nbsp;ssize_t wrote;
&lt;br&gt;&amp;nbsp; &amp;nbsp;int rclen, len;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp;if (sock == NULL) return rc; &amp;nbsp;/* journal replay mode */
&lt;br&gt;+ &amp;nbsp;if (JOURNAL_REPLAY(sock)) return rc;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;if (sock-&amp;gt;batch_start)
&lt;br&gt;&amp;nbsp; &amp;nbsp;{
&lt;br&gt;@@ -1043,7 +1044,7 @@ static int check_file_access (const char *file, listen_socket_t *sock) /* {{{ */
&lt;br&gt;&amp;nbsp; &amp;nbsp;assert(file != NULL);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;if (!config_write_base_only
&lt;br&gt;- &amp;nbsp; &amp;nbsp; &amp;nbsp;|| sock == NULL /* journal replay */
&lt;br&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp;|| JOURNAL_REPLAY(sock)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|| config_base_dir == NULL)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return 1;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;@@ -1272,7 +1273,7 @@ static int handle_request_forget(HANDLER_PROTO) /* {{{ */
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;if (found == TRUE)
&lt;br&gt;&amp;nbsp; &amp;nbsp;{
&lt;br&gt;- &amp;nbsp; &amp;nbsp;if (sock != NULL)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;if (!JOURNAL_REPLAY(sock))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;journal_write(&amp;quot;forget&amp;quot;, file);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return send_response(sock, RESP_OK, &amp;quot;Gone!\n&amp;quot;);
&lt;br&gt;@@ -1312,7 +1313,7 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */
&lt;br&gt;&amp;nbsp; &amp;nbsp;cache_item_t *ci;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;/* save it for the journal later */
&lt;br&gt;- &amp;nbsp;if (sock != NULL)
&lt;br&gt;+ &amp;nbsp;if (!JOURNAL_REPLAY(sock))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;strncpy(orig_buf, buffer, buffer_size);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;status = buffer_get_field (&amp;buffer, &amp;buffer_size, &amp;file);
&lt;br&gt;@@ -1398,7 +1399,7 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */
&lt;br&gt;&amp;nbsp; &amp;nbsp;assert (ci != NULL);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;/* don't re-write updates in replay mode */
&lt;br&gt;- &amp;nbsp;if (sock != NULL)
&lt;br&gt;+ &amp;nbsp;if (!JOURNAL_REPLAY(sock))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;journal_write(&amp;quot;update&amp;quot;, orig_buf);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;while (buffer_size &amp;gt; 0)
&lt;br&gt;@@ -1674,7 +1675,7 @@ static int socket_permission_check (listen_socket_t *sock, /* {{{ */
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp;ssize_t i;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;- &amp;nbsp;if (sock == NULL) /* journal replay */
&lt;br&gt;+ &amp;nbsp;if (JOURNAL_REPLAY(sock))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return (1);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;if (cmd == NULL)
&lt;br&gt;@@ -1713,7 +1714,7 @@ static int socket_permission_add (listen_socket_t *sock, /* {{{ */
&lt;br&gt;&amp;nbsp;/* check whether commands are received in the expected context */
&lt;br&gt;&amp;nbsp;static int command_check_context(listen_socket_t *sock, command_t *cmd)
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;- &amp;nbsp;if (sock == NULL)
&lt;br&gt;+ &amp;nbsp;if (JOURNAL_REPLAY(sock))
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return (cmd-&amp;gt;context &amp; CMD_CONTEXT_JOURNAL);
&lt;br&gt;&amp;nbsp; &amp;nbsp;else if (sock-&amp;gt;batch_start)
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;return (cmd-&amp;gt;context &amp; CMD_CONTEXT_BATCH);
&lt;br&gt;@@ -1765,7 +1766,6 @@ static int handle_request_help (HANDLER_PROTO) /* {{{ */
&lt;br&gt;&amp;nbsp; &amp;nbsp;return send_response(sock, RESP_OK, resp_txt);
&lt;br&gt;&amp;nbsp;} /* }}} int handle_request_help */
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-/* if sock==NULL, we are in journal replay mode */
&lt;br&gt;&amp;nbsp;static int handle_request (DISPATCH_PROTO) /* {{{ */
&lt;br&gt;&amp;nbsp;{
&lt;br&gt;&amp;nbsp; &amp;nbsp;char *buffer_ptr = buffer;
&lt;br&gt;-- 
&lt;br&gt;1.6.4
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26135576&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--JOURNAL_REPLAY-macro-clarifies-our-intentions-tp26135576p26135576.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26133551</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-30T09:57:44Z</published>
	<updated>2009-10-30T09:57:44Z</updated>
	<author>
		<name>kevin brintnall</name>
	</author>
	<content type="html">On Fri, Oct 30, 2009 at 09:47:43AM -0700, Thorsten von Eicken wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; &amp;gt; What's the start time on that daemon? &amp;nbsp;If it was started slightly before
&lt;br&gt;&amp;gt; &amp;gt; the graphs (~21:30-21:35), then it's possible that the CPU increase is
&lt;br&gt;&amp;gt; &amp;gt; associated with the first flush (-f).
&lt;br&gt;&amp;gt; &amp;gt; &amp;nbsp; 
&lt;br&gt;&amp;gt; It was right at the start of the graphs. If you look at the 
&lt;br&gt;&amp;gt; &amp;quot;write-data_sets&amp;quot; graph, you can see very clearly how the flushing 
&lt;br&gt;&amp;gt; starts at 22:38-22:39 and the first hour of flushing ends 23:46-23:47. 
&lt;br&gt;&amp;gt; The cpu spike starts to build at 23:26-23:28 so it's not on a clean 
&lt;br&gt;&amp;gt; boundary at all.If you look at the if-packets graph you can see how 
&lt;br&gt;&amp;gt; inbound traffic is 100% stable throughout the whole run.
&lt;/div&gt;&lt;br&gt;OK.. &amp;nbsp;That's what I thought :|
&lt;br&gt;&lt;br&gt;&amp;gt; &amp;gt; Something is queueing a lot of files; I would only expect that to
&lt;br&gt;&amp;gt; &amp;gt; result from the flush process if writing had stopped for a set of your
&lt;br&gt;&amp;gt; &amp;gt; RRDs. &amp;nbsp;For example, if you have a large number of RRD files in the
&lt;br&gt;&amp;gt; &amp;gt; journal that aren't being re-written afterwards, then the first flush
&lt;br&gt;&amp;gt; &amp;gt; would contain all those.
&lt;br&gt;&lt;br&gt;When the queue length jumps up, try issuing the &amp;quot;QUEUE&amp;quot; command to the
&lt;br&gt;daemon. &amp;nbsp;Maybe the list of queued files (or their order) will be
&lt;br&gt;instructive.
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;&amp;nbsp;kevin brintnall =~ /&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26133551&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;kbrint@...&lt;/a&gt;/
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26133551&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26133551.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26133400</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-30T09:47:43Z</published>
	<updated>2009-10-30T09:47:43Z</updated>
	<author>
		<name>Thorsten von Eicken</name>
	</author>
	<content type="html">kevin brintnall wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; On Fri, Oct 30, 2009 at 09:19:30AM -0700, Thorsten von Eicken wrote:
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;br&gt;&amp;gt;&amp;gt; Thorsten von Eicken wrote:
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; 37.1 % of the time it spent in ?handle_request_update? the daemon is
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; actually waiting for ?realloc?. This is (to me) very unexpected and a
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; schoolbook example of ?measure before you optimize?.
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; I think we can get rid of this bottleneck by writing a specialized
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; version of ?rrd_add_strdup? which reallocates powers of ten. Something
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; like:
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; [...]
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; It'd be great if you could give the attached patch a try
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; spends all of its time (more than 99 %) in ?realloc?. So in consequence
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; Test is running, including Kevin's simplification... Thanks for the 
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; help!!!
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;gt;&amp;gt; Things are again looking much better, almost great I should say! The one 
&lt;br&gt;&amp;gt;&amp;gt; thing that still makes me a bit uncomfortable is that at the end of the 
&lt;br&gt;&amp;gt;&amp;gt; second hour of run-time there was a cpu spike which caused collectd to 
&lt;br&gt;&amp;gt;&amp;gt; grow rapidly. (Still using -w 3600 -z 3600 -f 7200, I put a load of ~50k 
&lt;br&gt;&amp;gt;&amp;gt; tree nodes right from the start.) You can see the graphs at 
&lt;br&gt;&amp;gt;&amp;gt; &lt;a href=&quot;http://www.voneicken.com/dl/rrd/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.voneicken.com/dl/rrd/&lt;/a&gt;&amp;nbsp;look for the rrdcached-6* series. It 
&lt;br&gt;&amp;gt;&amp;gt; flattens out nicely after the spike, but it's one of those things that 
&lt;br&gt;&amp;gt;&amp;gt; tend to bite sooner or later. I'm not sure what to do about it.
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Thorsten,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; What's the start time on that daemon? &amp;nbsp;If it was started slightly before
&lt;br&gt;&amp;gt; the graphs (~21:30-21:35), then it's possible that the CPU increase is
&lt;br&gt;&amp;gt; associated with the first flush (-f).
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;/div&gt;It was right at the start of the graphs. If you look at the 
&lt;br&gt;&amp;quot;write-data_sets&amp;quot; graph, you can see very clearly how the flushing 
&lt;br&gt;starts at 22:38-22:39 and the first hour of flushing ends 23:46-23:47. 
&lt;br&gt;The cpu spike starts to build at 23:26-23:28 so it's not on a clean 
&lt;br&gt;boundary at all.If you look at the if-packets graph you can see how 
&lt;br&gt;inbound traffic is 100% stable throughout the whole run.
&lt;br&gt;&amp;gt; Something is queueing a lot of files; I would only expect that to result
&lt;br&gt;&amp;gt; from the flush process if writing had stopped for a set of your RRDs. &amp;nbsp;For
&lt;br&gt;&amp;gt; example, if you have a large number of RRD files in the journal that
&lt;br&gt;&amp;gt; aren't being re-written afterwards, then the first flush would contain all
&lt;br&gt;&amp;gt; those.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Did you use journal on startup for this test?
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;br&gt;I cleared the journals before starting rrdcached.
&lt;br&gt;&amp;gt; If you could profile during that &amp;quot;hump&amp;quot; it would be very instructive...
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;br&gt;Yeah, no kidding. The question is how to reproduce this given the 
&lt;br&gt;callgrind slow-down. I may try later next week when I hope to have some 
&lt;br&gt;more time.
&lt;br&gt;&lt;br&gt;Thorsten
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26133400&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26133400.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26133169</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-30T09:31:44Z</published>
	<updated>2009-10-30T09:31:44Z</updated>
	<author>
		<name>kevin brintnall</name>
	</author>
	<content type="html">On Fri, Oct 30, 2009 at 09:19:30AM -0700, Thorsten von Eicken wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Thorsten von Eicken wrote:
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; 37.1 % of the time it spent in ?handle_request_update? the daemon is
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; actually waiting for ?realloc?. This is (to me) very unexpected and a
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; schoolbook example of ?measure before you optimize?.
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; I think we can get rid of this bottleneck by writing a specialized
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; version of ?rrd_add_strdup? which reallocates powers of ten. Something
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; like:
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; [...]
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt; It'd be great if you could give the attached patch a try
&lt;br&gt;&amp;gt; &amp;gt; spends all of its time (more than 99 %) in ?realloc?. So in consequence
&lt;br&gt;&amp;gt; &amp;gt; Test is running, including Kevin's simplification... Thanks for the 
&lt;br&gt;&amp;gt; &amp;gt; help!!!
&lt;br&gt;&amp;gt; Things are again looking much better, almost great I should say! The one 
&lt;br&gt;&amp;gt; thing that still makes me a bit uncomfortable is that at the end of the 
&lt;br&gt;&amp;gt; second hour of run-time there was a cpu spike which caused collectd to 
&lt;br&gt;&amp;gt; grow rapidly. (Still using -w 3600 -z 3600 -f 7200, I put a load of ~50k 
&lt;br&gt;&amp;gt; tree nodes right from the start.) You can see the graphs at 
&lt;br&gt;&amp;gt; &lt;a href=&quot;http://www.voneicken.com/dl/rrd/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.voneicken.com/dl/rrd/&lt;/a&gt;&amp;nbsp;look for the rrdcached-6* series. It 
&lt;br&gt;&amp;gt; flattens out nicely after the spike, but it's one of those things that 
&lt;br&gt;&amp;gt; tend to bite sooner or later. I'm not sure what to do about it.
&lt;/div&gt;&lt;br&gt;Thorsten,
&lt;br&gt;&lt;br&gt;What's the start time on that daemon? &amp;nbsp;If it was started slightly before
&lt;br&gt;the graphs (~21:30-21:35), then it's possible that the CPU increase is
&lt;br&gt;associated with the first flush (-f).
&lt;br&gt;&lt;br&gt;Something is queueing a lot of files; I would only expect that to result
&lt;br&gt;from the flush process if writing had stopped for a set of your RRDs. &amp;nbsp;For
&lt;br&gt;example, if you have a large number of RRD files in the journal that
&lt;br&gt;aren't being re-written afterwards, then the first flush would contain all
&lt;br&gt;those.
&lt;br&gt;&lt;br&gt;Did you use journal on startup for this test?
&lt;br&gt;&lt;br&gt;If you could profile during that &amp;quot;hump&amp;quot; it would be very instructive...
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;&amp;nbsp;kevin brintnall =~ /&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26133169&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;kbrint@...&lt;/a&gt;/
&lt;br&gt;&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26133169&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26133169.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26132951</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-30T09:19:30Z</published>
	<updated>2009-10-30T09:19:30Z</updated>
	<author>
		<name>Thorsten von Eicken</name>
	</author>
	<content type="html">Thorsten von Eicken wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt;&amp;gt; 37.1 % of the time it spent in “handle_request_update” the daemon is
&lt;br&gt;&amp;gt;&amp;gt; actually waiting for “realloc”. This is (to me) very unexpected and a
&lt;br&gt;&amp;gt;&amp;gt; schoolbook example of “measure before you optimize”.
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; I think we can get rid of this bottleneck by writing a specialized
&lt;br&gt;&amp;gt;&amp;gt; version of “rrd_add_strdup” which reallocates powers of ten. Something
&lt;br&gt;&amp;gt;&amp;gt; like:
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; [...]
&lt;br&gt;&amp;gt;&amp;gt;
&lt;br&gt;&amp;gt;&amp;gt; It'd be great if you could give the attached patch a try
&lt;br&gt;&amp;gt; spends all of its time (more than 99 %) in “realloc”. So in consequence
&lt;br&gt;&amp;gt; Test is running, including Kevin's simplification... Thanks for the 
&lt;br&gt;&amp;gt; help!!!
&lt;/div&gt;Things are again looking much better, almost great I should say! The one 
&lt;br&gt;thing that still makes me a bit uncomfortable is that at the end of the 
&lt;br&gt;second hour of run-time there was a cpu spike which caused collectd to 
&lt;br&gt;grow rapidly. (Still using -w 3600 -z 3600 -f 7200, I put a load of ~50k 
&lt;br&gt;tree nodes right from the start.) You can see the graphs at 
&lt;br&gt;&lt;a href=&quot;http://www.voneicken.com/dl/rrd/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.voneicken.com/dl/rrd/&lt;/a&gt;&amp;nbsp;look for the rrdcached-6* series. It 
&lt;br&gt;flattens out nicely after the spike, but it's one of those things that 
&lt;br&gt;tend to bite sooner or later. I'm not sure what to do about it.
&lt;br&gt;Thorsten
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26132951&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26132951.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26125184</id>
	<title>rrdcached protocol issue: clients don't reconnect</title>
	<published>2009-10-29T22:20:53Z</published>
	<updated>2009-10-29T22:20:53Z</updated>
	<author>
		<name>Thorsten von Eicken</name>
	</author>
	<content type="html">I'm having problems with clients not reconnecting if I restart the 
&lt;br&gt;rrdcached daemon. For example, collectd prints out the following type of 
&lt;br&gt;error forever if I do a &amp;quot;service rrdcached restart&amp;quot; (using unix socket, 
&lt;br&gt;but I believe same happens with TCP):
&lt;br&gt;&lt;br&gt;Oct 30 05:03:52 sketchy1-1b collectd[3551]: rrdcached plugin: 
&lt;br&gt;rrdc_update (/rrds/.../memcached_command-set.rrd, 
&lt;br&gt;[1256878677:2904863359], 1) failed with status -3.
&lt;br&gt;&lt;br&gt;I believe this comes from rrd_client.c in response_read:
&lt;br&gt;&amp;nbsp; buffer_ptr = fgets (buffer, sizeof (buffer), sh);
&lt;br&gt;&amp;nbsp; if (buffer_ptr == NULL)
&lt;br&gt;&amp;nbsp; &amp;nbsp; return (-3);
&lt;br&gt;&amp;nbsp; chomp (buffer);
&lt;br&gt;&lt;br&gt;Seems to me that this is to be expected:
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;quot;gets() and fgets() return s on success, and NULL on error or 
&lt;br&gt;when end of file &amp;nbsp;occurs
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;while no characters have been read.&amp;quot;
&lt;br&gt;&lt;br&gt;The proper error handling to close the connection seems to be missing?
&lt;br&gt;&lt;br&gt;Thorsten
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26125184&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/rrdcached-protocol-issue%3A-clients-don%27t-reconnect-tp26125184p26125184.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26125008</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-29T21:55:07Z</published>
	<updated>2009-10-29T21:55:07Z</updated>
	<author>
		<name>Thorsten von Eicken</name>
	</author>
	<content type="html">Florian Forster wrote:
&lt;br&gt;&amp;gt;&amp;gt; 547,131,570 &amp;nbsp;&amp;lt; rrd_daemon.c:queue_thread_main'2 (263x) [/usr/bin/rrdcached]
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp; 3,186,524 &amp;nbsp;&amp;lt; rrd_daemon.c:queue_thread_main (3x) [/usr/bin/rrdcached]
&lt;br&gt;&amp;gt;&amp;gt; 550,318,094 &amp;nbsp;* &amp;nbsp;rrd_update.c:rrd_update_r [/usr/lib64/librrd_th.so.4.1.0]
&lt;br&gt;&amp;gt;&amp;gt; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I wonder where this second update thread is coming from. Did you
&lt;br&gt;&amp;gt; configure one or two? If you configured two, why isn't the second one
&lt;br&gt;&amp;gt; doing any real work?
&lt;br&gt;&amp;gt; &amp;nbsp; 
&lt;br&gt;Yes, there are two configured. Your question is a good one. If I get to 
&lt;br&gt;run callgrind again I'll run it a bit longer and we'll see whether it 
&lt;br&gt;was due to the short observation window. I don't know how the 
&lt;br&gt;locking/dequeueing primitives work, is there perhaps something that 
&lt;br&gt;prefers one thread and the second doesn't run if the first one is fast 
&lt;br&gt;enough at dequeueing?
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; spends all of its time (more than 99 %) in “realloc”. So in consequence
&lt;br&gt;&amp;gt; 37.1 % of the time it spent in “handle_request_update” the daemon is
&lt;br&gt;&amp;gt; actually waiting for “realloc”. This is (to me) very unexpected and a
&lt;br&gt;&amp;gt; schoolbook example of “measure before you optimize”.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I think we can get rid of this bottleneck by writing a specialized
&lt;br&gt;&amp;gt; version of “rrd_add_strdup” which reallocates powers of ten. Something
&lt;br&gt;&amp;gt; like:
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; [...]
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; It'd be great if you could give the attached patch a try
&lt;/div&gt;Test is running, including Kevin's simplification... Thanks for the help!!!
&lt;br&gt;&lt;br&gt;By the way, we were calculating some stats the other day and noticed 
&lt;br&gt;that we're collecting 680k RRDs (most have 1 DS) every 20 seconds. 
&lt;br&gt;That's 35K RRD updates per second. No, this is not on one server...
&lt;br&gt;&lt;br&gt;Cheers,
&lt;br&gt;Thorsten
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26125008&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26125008.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26113296</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-29T06:44:57Z</published>
	<updated>2009-10-29T06:44:57Z</updated>
	<author>
		<name>kevin brintnall</name>
	</author>
	<content type="html">&amp;gt; spends all of its time (more than 99??%) in ???realloc???. So in consequence
&lt;br&gt;&amp;gt; 37.1??% of the time it spent in ???handle_request_update??? the daemon is
&lt;br&gt;&amp;gt; actually waiting for ???realloc???. This is (to me) very unexpected and a
&lt;br&gt;&amp;gt; schoolbook example of ???measure before you optimize???.
&lt;br&gt;&lt;br&gt;Florian et al,
&lt;br&gt;&lt;br&gt;I'd rather see the realloc in linear chunks vs. exponential.. i.e. when we
&lt;br&gt;run out, allocate another X pointers. &amp;nbsp;We'll still reduce calls to
&lt;br&gt;realloc(), but without risking exponential jumps in memory utilization.
&lt;br&gt;&lt;br&gt;i.e. we could add cache_item_t-&amp;gt;values_alloc to keep track of how many
&lt;br&gt;values have been allocated. &amp;nbsp;Then, we can realloc() a new chunk on demand.
&lt;br&gt;This chunk size could even be configurable.. &amp;nbsp;a clever admin could
&lt;br&gt;pre-allocate all the pointers (i.e. &amp;quot;-w&amp;quot;/rrd_step).
&lt;br&gt;&lt;br&gt;P.S.: is_power_of_two = old_size &amp;&amp; !(old_size &amp; (old_size-1));
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;&amp;nbsp;kevin brintnall =~ /&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26113296&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;kbrint@...&lt;/a&gt;/
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; + &amp;nbsp;if (old_size &amp;gt; 0)
&lt;br&gt;&amp;gt; + &amp;nbsp;{
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;is_power_of_two = old_size;
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;while ((is_power_of_two &amp; 0x01) == 0)
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp;is_power_of_two &amp;gt;&amp;gt;= 1;
&lt;br&gt;&amp;gt; + &amp;nbsp;}
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; + &amp;nbsp;/* If the current size is a power of two (or zero), increase the array size.
&lt;br&gt;&amp;gt; + &amp;nbsp; * Otherwise enough space has been allocated previously. */
&lt;br&gt;&amp;gt; + &amp;nbsp;if (old_size == 0)
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;new_size = 1;
&lt;br&gt;&amp;gt; + &amp;nbsp;else if (is_power_of_two == 1)
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;new_size = 2 * old_size;
&lt;br&gt;&amp;gt; + &amp;nbsp;else
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;new_size = old_size;
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; + &amp;nbsp;/* We need to allocate more space. */
&lt;br&gt;&amp;gt; + &amp;nbsp;if (new_size != old_size)
&lt;br&gt;&amp;gt; + &amp;nbsp;{
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;char **tmp;
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;tmp = realloc (*dest, new_size * sizeof (char *));
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;if (tmp == NULL)
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp; &amp;nbsp;return (ENOMEM);
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;*dest = tmp;
&lt;br&gt;&amp;gt; + &amp;nbsp;}
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; + &amp;nbsp;/* Duplicate the string. On error, the array size is not decreased. This
&lt;br&gt;&amp;gt; + &amp;nbsp; * means the callee may have to free `dest' even if this function failed. */
&lt;br&gt;&amp;gt; + &amp;nbsp;(*dest)[old_size] = strdup (src);
&lt;br&gt;&amp;gt; + &amp;nbsp;if ((*dest)[old_size] == NULL)
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;return (ENOMEM);
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; + &amp;nbsp;*dest_size = old_size + 1;
&lt;br&gt;&amp;gt; + &amp;nbsp;return (0);
&lt;br&gt;&amp;gt; +} /* }}} int add_strdup_exp */
&lt;br&gt;&amp;gt; +
&lt;br&gt;&amp;gt; &amp;nbsp;static int count_lines(char *str) /* {{{ */
&lt;br&gt;&amp;gt; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;int lines = 0;
&lt;br&gt;&amp;gt; @@ -1433,7 +1486,7 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;else
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ci-&amp;gt;last_update_stamp = stamp;
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt; - &amp;nbsp; &amp;nbsp;if (!rrd_add_strdup(&amp;ci-&amp;gt;values, &amp;ci-&amp;gt;values_num, value))
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;if (add_strdup_exp (&amp;ci-&amp;gt;values, &amp;ci-&amp;gt;values_num, value) != 0)
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp;{
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;RRDD_LOG (LOG_ERR, &amp;quot;handle_request_update: rrd_add_strdup failed.&amp;quot;);
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue;
&lt;br&gt;&amp;gt; -- 
&lt;br&gt;&amp;gt; 1.6.3.3
&lt;br&gt;&amp;gt; 
&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26113296&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26113296.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26109140</id>
	<title>Re: rrdcached performance problem</title>
	<published>2009-10-29T01:40:05Z</published>
	<updated>2009-10-29T01:40:05Z</updated>
	<author>
		<name>Sebastian Harl</name>
	</author>
	<content type="html">Hi,
&lt;br&gt;&lt;br&gt;On Wed, Oct 28, 2009 at 11:25:03PM -0700, Thorsten von Eicken wrote:
&lt;br&gt;&amp;gt; it's clearly active both receiving and flushing, and realloc is the
&lt;br&gt;&amp;gt; top primitive that I see. Mhhh, I haven't dealt with these things in
&lt;br&gt;&amp;gt; eons so I'll have to see whether there's a different distro I can use
&lt;br&gt;&amp;gt; to get a better realloc implementation.
&lt;br&gt;&lt;br&gt;Disclaimer: I have not looked into the whole issue in detail yet, this
&lt;br&gt;is just a more or less wild guess … ;-)
&lt;br&gt;&lt;br&gt;You're on Linux, right? So, I presume, you're using the GNU libc. IIrc,
&lt;br&gt;the glibc memory management implementation (*alloc, free) is optimized
&lt;br&gt;for memory usage rather than speed, so the speed is (supposedly - did
&lt;br&gt;not check that myself) rather slow.
&lt;br&gt;&lt;br&gt;This might also further explain why Kevin did not stumble across that
&lt;br&gt;issue, since (iIrc) he's on FreeBSD which might have a &amp;quot;better&amp;quot; (speed-
&lt;br&gt;wise) implementation of those functions.
&lt;br&gt;&lt;br&gt;Since we're using the glib (as in GNOME lib - note the missing 'c' ;-))
&lt;br&gt;anyway, we might give it a try to use their memory management functions
&lt;br&gt;(g_*malloc*, g_free) - those are supposed to be quite a bit faster (yet,
&lt;br&gt;I did not check that myself neither).
&lt;br&gt;&lt;br&gt;Cheers,
&lt;br&gt;Sebastian
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Sebastian &amp;quot;tokkee&amp;quot; Harl +++ GnuPG-ID: 0x8501C7FC +++ &lt;a href=&quot;http://tokkee.org/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://tokkee.org/&lt;/a&gt;&lt;br&gt;&lt;br&gt;Those who would give up Essential Liberty to purchase a little Temporary
&lt;br&gt;Safety, deserve neither Liberty nor Safety. &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -- Benjamin Franklin
&lt;br&gt;&lt;br&gt;&lt;br /&gt; &lt;br /&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26109140&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;&lt;div class=&quot;small&quot;&gt;&lt;br/&gt;&lt;img src=&quot;http://old.nabble.com/images/icon_attachment.gif&quot; &gt; &lt;strong&gt;signature.asc&lt;/strong&gt; (204 bytes) &lt;a href=&quot;http://old.nabble.com/attachment/26109140/0/signature.asc&quot; target=&quot;_top&quot;&gt;Download Attachment&lt;/a&gt;&lt;/div&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/Re%3A-rrdcached-performance-problem-tp26109140p26109140.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26101216</id>
	<title>RRDtool 1.4 - higher Performance and cool Features</title>
	<published>2009-10-28T12:59:33Z</published>
	<updated>2009-10-28T12:59:33Z</updated>
	<author>
		<name>Tobias Oetiker-3</name>
	</author>
	<content type="html">Just in time for LISA'09 I am releasing the all new RRDtool 1.4.
&lt;br&gt;RRDtool 1.4 comes with a much anticipated RRDcache Daemon, elevating the
&lt;br&gt;system to new performance levels it also contains a host of new and
&lt;br&gt;improved features. See the List below. Get your copy from:
&lt;br&gt;&lt;br&gt;&amp;nbsp; &lt;a href=&quot;http://oss.oetiker.ch/rrdtool/&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://oss.oetiker.ch/rrdtool/&lt;/a&gt;&lt;br&gt;&lt;br&gt;cheers tobi
&lt;br&gt;&lt;br&gt;Brought to you by the 2009 RRDtool sponsors:
&lt;br&gt;-----------------------------------------------------------------------
&lt;br&gt;GOLD: &amp;nbsp; &lt;a href=&quot;http://www.zenoss.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.zenoss.com&lt;/a&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;a href=&quot;http://www.groundworkopensource.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.groundworkopensource.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;SILVER: &lt;a href=&quot;http://www.digicomp.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.digicomp.ch&lt;/a&gt;&amp;nbsp; &lt;a href=&quot;http://www.atc-onlane.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.atc-onlane.com&lt;/a&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;a href=&quot;http://www.terreactive.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.terreactive.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://hosteurope.de&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://hosteurope.de&lt;/a&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;a href=&quot;http://www.hitmeister.de&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.hitmeister.de&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://www.contego.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.contego.com&lt;/a&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;a href=&quot;http://www.sidarion.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://www.sidarion.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://chinavasion.com&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://chinavasion.com&lt;/a&gt;&lt;br&gt;-----------------------------------------------------------------------
&lt;br&gt;ps. if you would like to become a sponsor for 2010, be in touch!
&lt;br&gt;&lt;br&gt;#####################################
&lt;br&gt;Major Changes between 1.3.x and 1.4.x
&lt;br&gt;-------------------------------------
&lt;br&gt;$Id: NEWS 1958 2009-10-27 21:40:09Z oetiker $
&lt;br&gt;&lt;br&gt;RRD Caching Daemon (rrdcached)
&lt;br&gt;------------------------------
&lt;br&gt;by Florian Forster and Kevin Brintnall
&lt;br&gt;&lt;br&gt;The RRD Caching Daemon can dramatically improve the 'update' performance
&lt;br&gt;of your system. &amp;nbsp;Due to file handling overheads, the time it takes todo one
&lt;br&gt;update is virtually the same as to doing two updates in a row.
&lt;br&gt;&lt;br&gt;The Cache Daemon intercepts rrdtool update calls, assembling multiple
&lt;br&gt;updates before writing them to the actual rrd file. When calling rrdtool
&lt;br&gt;graph in such a setup, the command will tell the daemon to flush out all
&lt;br&gt;pending updates for the rrd files, required to draw the graph.
&lt;br&gt;&lt;br&gt;See rrdcached documentation.
&lt;br&gt;&lt;br&gt;RRD Dumping and Restoring (rrdtool dump/restore)
&lt;br&gt;------------------------------------------------
&lt;br&gt;by Tobi Oetiker
&lt;br&gt;&lt;br&gt;The output of rrdtool dump has been adjusted to be simpler to parse by
&lt;br&gt;existing xml parsers.
&lt;br&gt;&lt;br&gt;The restore core has been completely re-written yet again and is now relying
&lt;br&gt;on an incremental xml parser. This has the advantage that the memory
&lt;br&gt;consumption while restoring xml files is only slightly larger than the
&lt;br&gt;resulting rrd file. Which is much less than the requirements of the 1.3 and
&lt;br&gt;even 1.2
&lt;br&gt;&lt;br&gt;RRD Graphing functions (rrdtool graph)
&lt;br&gt;--------------------------------------
&lt;br&gt;by Martin Sperl
&lt;br&gt;&lt;br&gt;* VDEF PERCENTNAN (a PRECENT that ignores NAN)
&lt;br&gt;&lt;br&gt;* CDEF PREDICT and PREDICTSIGMA functions for on-the-fly
&lt;br&gt;&amp;nbsp; data prediction without the need to modify existing rrd files as it is
&lt;br&gt;&amp;nbsp; required for HoltWinters.
&lt;br&gt;&lt;br&gt;* LibDBI integration provides a path to read data directly of a supported
&lt;br&gt;&amp;nbsp; SQL database into rrdtool graph. See rrdgraph_libdbi documentation.
&lt;br&gt;&lt;br&gt;Miscellaneous Changes
&lt;br&gt;---------------------
&lt;br&gt;* graph legends can now be placed left, right or above the graph with the
&lt;br&gt;&amp;nbsp; new --legend-direction and --legend-positon placement options.
&lt;br&gt;&amp;nbsp; by Melchior Rabe
&lt;br&gt;&lt;br&gt;* switched to using automake 1.11 which provides a 'silent' build process,
&lt;br&gt;&amp;nbsp; causing errors and warnings to stand out much more than before.
&lt;br&gt;&amp;nbsp; by Tobi Oetiker
&lt;br&gt;&lt;br&gt;* switched from intltoolize to autopoint for the i18n configuration.
&lt;br&gt;&amp;nbsp; by Tobi Oetiker
&lt;br&gt;&lt;br&gt;* new graph option --grid-dash on:off to configure the dash length
&lt;br&gt;&amp;nbsp; in the grid painted over the graph by Tobi Oetiker
&lt;br&gt;&lt;br&gt;* lua bindings for rrdtool
&lt;br&gt;&amp;nbsp; by Fidelis Assis
&lt;br&gt;&lt;br&gt;* various improvements to rrd_open functions and mmap handling
&lt;br&gt;&amp;nbsp; by Daniel Pocock
&lt;br&gt;&lt;br&gt;* allow the HW smoothing window size to be set to 0 with rrdtool tune
&lt;br&gt;&amp;nbsp; by sylvain luiset
&lt;br&gt;&lt;br&gt;* new graph option --border to set the 3d border width
&lt;br&gt;&amp;nbsp; by Bernhard Reutner-Fischer
&lt;br&gt;&lt;br&gt;* draw different color swats depending on the type of line drawn in the
&lt;br&gt;&amp;nbsp; graph by Loïc Tortay
&lt;br&gt;&lt;br&gt;for more detail see the CHANGES file.
&lt;br&gt;&lt;br&gt;-- 
&lt;br&gt;Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
&lt;br&gt;&lt;a href=&quot;http://it.oetiker.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://it.oetiker.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26101216&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tobi@...&lt;/a&gt; ++41 62 775 9902 / sb: -9900&lt;br /&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26101216&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/RRDtool-1.4---higher-Performance-and-cool-Features-tp26101216p26101216.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26089518</id>
	<title>Re: [PATCH] Avoid unnecessary string handling for UPDATE commands.</title>
	<published>2009-10-27T22:18:19Z</published>
	<updated>2009-10-27T22:18:19Z</updated>
	<author>
		<name>Tobias Oetiker-3</name>
	</author>
	<content type="html">Hi Kevin,
&lt;br&gt;&lt;br&gt;Today kevin brintnall wrote:
&lt;br&gt;&lt;br&gt;&amp;gt; &amp;nbsp;- only copy as many bytes as necessary
&lt;br&gt;&amp;gt; &amp;nbsp;- during journal replay, avoid unnecessary copy (string is discarded)
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Thank you Thorsten von Eicken &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26089518&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tve@...&lt;/a&gt;&amp;gt;
&lt;br&gt;&lt;br&gt;you di have perfect timing :-) so it will be an 1.4.1 announement today. But I
&lt;br&gt;guess the performance impact is well worth it. Thank you!
&lt;br&gt;&lt;br&gt;cheers
&lt;br&gt;tobi
&lt;br&gt;&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; ---
&lt;br&gt;&amp;gt; &amp;nbsp;src/rrd_daemon.c | &amp;nbsp; &amp;nbsp;3 ++-
&lt;br&gt;&amp;gt; &amp;nbsp;1 files changed, 2 insertions(+), 1 deletions(-)
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c
&lt;br&gt;&amp;gt; index 0ca1818..1946003 100644
&lt;br&gt;&amp;gt; --- a/src/rrd_daemon.c
&lt;br&gt;&amp;gt; +++ b/src/rrd_daemon.c
&lt;br&gt;&amp;gt; @@ -1312,7 +1312,8 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;cache_item_t *ci;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;/* save it for the journal later */
&lt;br&gt;&amp;gt; - &amp;nbsp;strncpy(orig_buf, buffer, sizeof(orig_buf)-1);
&lt;br&gt;&amp;gt; + &amp;nbsp;if (sock != NULL)
&lt;br&gt;&amp;gt; + &amp;nbsp; &amp;nbsp;strncpy(orig_buf, buffer, buffer_size);
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;status = buffer_get_field (&amp;buffer, &amp;buffer_size, &amp;file);
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;if (status != 0)
&lt;br&gt;&amp;gt;
&lt;/div&gt;&lt;br&gt;-- 
&lt;br&gt;Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
&lt;br&gt;&lt;a href=&quot;http://it.oetiker.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://it.oetiker.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26089518&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tobi@...&lt;/a&gt; ++41 62 775 9902 / sb: -9900
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26089518&amp;i=2&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--Avoid-unnecessary-string-handling-for-UPDATE-commands.-tp26088991p26089518.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26088991</id>
	<title>[PATCH] Avoid unnecessary string handling for UPDATE commands.</title>
	<published>2009-10-27T20:52:44Z</published>
	<updated>2009-10-27T20:52:44Z</updated>
	<author>
		<name>kevin brintnall</name>
	</author>
	<content type="html">&amp;nbsp;- only copy as many bytes as necessary
&lt;br&gt;&amp;nbsp;- during journal replay, avoid unnecessary copy (string is discarded)
&lt;br&gt;&lt;br&gt;Thank you Thorsten von Eicken &amp;lt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26088991&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tve@...&lt;/a&gt;&amp;gt;
&lt;br&gt;---
&lt;br&gt;&amp;nbsp;src/rrd_daemon.c | &amp;nbsp; &amp;nbsp;3 ++-
&lt;br&gt;&amp;nbsp;1 files changed, 2 insertions(+), 1 deletions(-)
&lt;br&gt;&lt;br&gt;diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c
&lt;br&gt;index 0ca1818..1946003 100644
&lt;br&gt;--- a/src/rrd_daemon.c
&lt;br&gt;+++ b/src/rrd_daemon.c
&lt;br&gt;@@ -1312,7 +1312,8 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */
&lt;br&gt;&amp;nbsp; &amp;nbsp;cache_item_t *ci;
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;/* save it for the journal later */
&lt;br&gt;- &amp;nbsp;strncpy(orig_buf, buffer, sizeof(orig_buf)-1);
&lt;br&gt;+ &amp;nbsp;if (sock != NULL)
&lt;br&gt;+ &amp;nbsp; &amp;nbsp;strncpy(orig_buf, buffer, buffer_size);
&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;nbsp; &amp;nbsp;status = buffer_get_field (&amp;buffer, &amp;buffer_size, &amp;file);
&lt;br&gt;&amp;nbsp; &amp;nbsp;if (status != 0)
&lt;br&gt;-- 
&lt;br&gt;1.6.4
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26088991&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/-PATCH--Avoid-unnecessary-string-handling-for-UPDATE-commands.-tp26088991p26088991.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26086960</id>
	<title>Re: No ordering information in info hash</title>
	<published>2009-10-27T16:33:34Z</published>
	<updated>2009-10-27T16:33:34Z</updated>
	<author>
		<name>Tobias Oetiker-3</name>
	</author>
	<content type="html">Hi Hermann,
&lt;br&gt;&lt;br&gt;try rrdtool-1.4.0.tar.gz ... which I just uploaded ... will
&lt;br&gt;announce tomorrow.
&lt;br&gt;&lt;br&gt;cheers
&lt;br&gt;tobi
&lt;br&gt;&lt;br&gt;Yesterday Hermann Lauer wrote:
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Hello Tobi,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; On Tue, Oct 27, 2009 at 09:43:40PM +0100, Tobias Oetiker wrote:
&lt;br&gt;&amp;gt; &amp;gt; Hi Hermann,
&lt;br&gt;&amp;gt; &amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; there was an extension recently added a ds[x].index entry which
&lt;br&gt;&amp;gt; &amp;gt; will help you resolve this problem ...
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Great. Sounds exactly like what I missed.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt; make sure you use a current snapshot of the archive ...
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Just downloaded rrdtool-trunk-svn-snap.tar.gz, which unpacked to
&lt;br&gt;&amp;gt; rrdtool-1.3.99909102700. &amp;quot;configure&amp;quot; and &amp;quot;make&amp;quot; ends with:
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; CC &amp;nbsp; &amp;nbsp; rrd_restore.lo
&lt;br&gt;&amp;gt; rrd_restore.c: In function ??rrd_restore??:
&lt;br&gt;&amp;gt; rrd_restore.c:1260: warning: implicit declaration of function ??setlocale??
&lt;br&gt;&amp;gt; rrd_restore.c:1260: warning: nested extern declaration of ??setlocale??
&lt;br&gt;&amp;gt; rrd_restore.c:1260: error: ??LC_NUMERIC?? undeclared (first use in this function)
&lt;br&gt;&amp;gt; rrd_restore.c:1260: error: (Each undeclared identifier is reported only once
&lt;br&gt;&amp;gt; rrd_restore.c:1260: error: for each function it appears in.)
&lt;br&gt;&amp;gt; rrd_restore.c:1260: warning: assignment makes pointer from integer without a cast
&lt;br&gt;&amp;gt; make[2]: *** [rrd_restore.lo] Error 1
&lt;br&gt;&amp;gt; make[2]: Leaving directory `/tmp/rrd/rrdtool-1.3.99909102700/src'
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; This is on a current debian lenny. Probably I should wait for the next
&lt;br&gt;&amp;gt; snapshot.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; But anyway, thanks for your help.
&lt;br&gt;&amp;gt; &amp;nbsp;Greetings
&lt;br&gt;&amp;gt; &amp;nbsp; Hermann
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;/div&gt;&lt;br&gt;-- 
&lt;br&gt;Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
&lt;br&gt;&lt;a href=&quot;http://it.oetiker.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://it.oetiker.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26086960&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tobi@...&lt;/a&gt; ++41 62 775 9902 / sb: -9900
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26086960&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/No-ordering-information-in-info-hash-tp26078900p26086960.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26084895</id>
	<title>Re: No ordering information in info hash</title>
	<published>2009-10-27T13:43:40Z</published>
	<updated>2009-10-27T13:43:40Z</updated>
	<author>
		<name>Tobias Oetiker-3</name>
	</author>
	<content type="html">Hi Hermann,
&lt;br&gt;&lt;br&gt;there was an extension recently added a ds[x].index entry which
&lt;br&gt;will help you resolve this problem ...
&lt;br&gt;&lt;br&gt;make sure you use a current snapshot of the archive ...
&lt;br&gt;&lt;br&gt;cheers
&lt;br&gt;tobi
&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;Today Hermann Lauer wrote:
&lt;br&gt;&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Hello all,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; I noticed that in the python bindings of rrdtool-1.3.99909060808
&lt;br&gt;&amp;gt; the rrdtool.info() function the datasources in the flat hash dict returned
&lt;br&gt;&amp;gt; are partly indexed with the datasource name and partly indexed with numbers
&lt;br&gt;&amp;gt; (see example below). Besides beeing somehow inconsistent a problem arises:
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; How to find out the ordering of datasources to
&lt;br&gt;&amp;gt; find the datasource name for the rra[].cdp_prep[] values (or for
&lt;br&gt;&amp;gt; using rrdtool.update('N:...:...:...')) without knowing the order
&lt;br&gt;&amp;gt; of the datasources.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; How is this handled in other bindings (e.g. perl) ?
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; Please tell me if I missed something obvious,
&lt;br&gt;&amp;gt; &amp;nbsp; greetings
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;Hermann
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; import rrdtool
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; rrdtool.__version__
&lt;br&gt;&amp;gt; '$Revision: 1.14 $'
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; rrdtool.create('/tmp/test.rrd','--step','20','DS:ds2:GAUGE:300:0:100','DS:x1:GAUGE:300:0:100','DS:ds0:GAUGE:300:-5:100','RRA:AVERAGE:0.5:3:2')
&lt;br&gt;&amp;gt; &amp;gt;&amp;gt;&amp;gt; rrdtool.info('/tmp/test.rrd')
&lt;br&gt;&amp;gt; {'rra[0].cdp_prep[0].value': None, 'ds[ds2].min': 0.0, 'ds[ds0].min': -5.0, 'rra[0].cdp_prep[1].unknown_datapoints': 1L, 'ds[ds2].value': 0.0, 'ds[ds2].last_ds': 'U', 'ds[x1].max': 100.0, 'ds[ds2].unknown_sec': 5L, 'ds[ds0].value': 0.0, 'ds[ds0].unknown_sec': 5L, 'ds[ds0].max': 100.0, 'ds[ds2].max': 100.0, 'rrd_version': '0003', 'filename': '/tmp/test.rrd', 'last_update': 1256646805L, 'rra[0].cf': 'AVERAGE', 'ds[x1].type': 'GAUGE', 'rra[0].pdp_per_row': 3L, 'rra[0].cur_row': 1L, 'header_size': 1172L, 'ds[ds0].last_ds': 'U', 'step': 20L, 'rra[0].cdp_prep[0].unknown_datapoints': 1L, 'ds[ds0].type': 'GAUGE', 'rra[0].cdp_prep[2].value': None, 'ds[x1].last_ds': 'U', 'ds[ds2].minimal_heartbeat': 300L, 'rra[0].rows': 2L, 'ds[x1].min': 0.0, 'ds[ds0].minimal_heartbeat': 300L, 'ds[x1].unknown_sec': 5L, 'rra[0].xff': 0.5, 'rra[0].cdp_prep[2].unknown_datapoints': 1L, 'ds[ds2].type': 'GAUGE', 'rra[0].cdp_prep[1].value': None, 'ds[x1].value': 0.0, 'ds[x1].minimal_heartbeat': 300L}
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;
&lt;/div&gt;&lt;br&gt;-- 
&lt;br&gt;Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
&lt;br&gt;&lt;a href=&quot;http://it.oetiker.ch&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;http://it.oetiker.ch&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26084895&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;tobi@...&lt;/a&gt; ++41 62 775 9902 / sb: -9900
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26084895&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/No-ordering-information-in-info-hash-tp26078900p26084895.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26220085</id>
	<title>Re: No ordering information in info hash</title>
	<published>2009-10-27T08:47:08Z</published>
	<updated>2009-10-27T08:47:08Z</updated>
	<author>
		<name>Duncan McGreggor-2</name>
	</author>
	<content type="html">Hermann Lauer wrote:
&lt;div class='shrinkable-quote'&gt;&lt;br&gt;&amp;gt; Hello all,
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; I noticed that in the python bindings of rrdtool-1.3.99909060808
&lt;br&gt;&amp;gt; the rrdtool.info() function the datasources in the flat hash dict returned
&lt;br&gt;&amp;gt; are partly indexed with the datasource name and partly indexed with numbers
&lt;br&gt;&amp;gt; (see example below). Besides beeing somehow inconsistent a problem arises:
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; How to find out the ordering of datasources to 
&lt;br&gt;&amp;gt; find the datasource name for the rra[].cdp_prep[] values (or for
&lt;br&gt;&amp;gt; using rrdtool.update('N:...:...:...')) without knowing the order
&lt;br&gt;&amp;gt; of the datasources.
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; How is this handled in other bindings (e.g. perl) ?
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; Please tell me if I missed something obvious,
&lt;br&gt;&amp;gt; &amp;nbsp; greetings
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;Hermann
&lt;br&gt;&amp;gt; 
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; import rrdtool
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; rrdtool.__version__
&lt;br&gt;&amp;gt; '$Revision: 1.14 $'
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; rrdtool.create('/tmp/test.rrd','--step','20','DS:ds2:GAUGE:300:0:100','DS:x1:GAUGE:300:0:100','DS:ds0:GAUGE:300:-5:100','RRA:AVERAGE:0.5:3:2')
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; rrdtool.info('/tmp/test.rrd')
&lt;br&gt;&amp;gt; {'rra[0].cdp_prep[0].value': None, 'ds[ds2].min': 0.0, 'ds[ds0].min': -5.0, 'rra[0].cdp_prep[1].unknown_datapoints': 1L, 'ds[ds2].value': 0.0, 'ds[ds2].last_ds': 'U', 'ds[x1].max': 100.0, 'ds[ds2].unknown_sec': 5L, 'ds[ds0].value': 0.0, 'ds[ds0].unknown_sec': 5L, 'ds[ds0].max': 100.0, 'ds[ds2].max': 100.0, 'rrd_version': '0003', 'filename': '/tmp/test.rrd', 'last_update': 1256646805L, 'rra[0].cf': 'AVERAGE', 'ds[x1].type': 'GAUGE', 'rra[0].pdp_per_row': 3L, 'rra[0].cur_row': 1L, 'header_size': 1172L, 'ds[ds0].last_ds': 'U', 'step': 20L, 'rra[0].cdp_prep[0].unknown_datapoints': 1L, 'ds[ds0].type': 'GAUGE', 'rra[0].cdp_prep[2].value': None, 'ds[x1].last_ds': 'U', 'ds[ds2].minimal_heartbeat': 300L, 'rra[0].rows': 2L, 'ds[x1].min': 0.0, 'ds[ds0].minimal_heartbeat': 300L, 'ds[x1].unknown_sec': 5L, 'rra[0].xff': 0.5, 'rra[0].cdp_prep[2].unknown_datapoints': 1L, 'ds[ds2].type': 'GAUGE', 'rra[0].cdp_prep[1].value': None, 'ds[x1].value': 0.0, 'ds[x1].minimal_heartbeat': 300L}
&lt;br&gt;&amp;gt; &amp;nbsp;
&lt;/div&gt;&lt;br&gt;Hey Herman,
&lt;br&gt;&lt;br&gt;It's important to note that both the keys and the values in that data
&lt;br&gt;tructure are strings -- don't let the form trick you :-) As such, you
&lt;br&gt;can simply sort them like this:
&lt;br&gt;&amp;nbsp; sorted(d.items())
&lt;br&gt;&lt;br&gt;And that will give you a list of (key, value) tuples that you can
&lt;br&gt;iterate through and check. Since these are string values, you have to do
&lt;br&gt;stringy things...
&lt;br&gt;&lt;br&gt;PyRRD does provide non-string keys in its data structures, so you have
&lt;br&gt;more flexibility. If you want to email the PyRRD list, we can talk about
&lt;br&gt;the type of data access you'd like to have... adding features like this
&lt;br&gt;to PyRRD is probably much easier than doing so to the RRDTool Python
&lt;br&gt;bindings.
&lt;br&gt;&lt;br&gt;Thanks,
&lt;br&gt;&lt;br&gt;d
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26220085&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/No-ordering-information-in-info-hash-tp26078900p26220085.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26078900</id>
	<title>No ordering information in info hash</title>
	<published>2009-10-27T06:14:09Z</published>
	<updated>2009-10-27T06:14:09Z</updated>
	<author>
		<name>Hermann Lauer</name>
	</author>
	<content type="html">Hello all,
&lt;br&gt;&lt;br&gt;I noticed that in the python bindings of rrdtool-1.3.99909060808
&lt;br&gt;the rrdtool.info() function the datasources in the flat hash dict returned
&lt;br&gt;are partly indexed with the datasource name and partly indexed with numbers
&lt;br&gt;(see example below). Besides beeing somehow inconsistent a problem arises:
&lt;br&gt;&lt;br&gt;How to find out the ordering of datasources to 
&lt;br&gt;find the datasource name for the rra[].cdp_prep[] values (or for
&lt;br&gt;using rrdtool.update('N:...:...:...')) without knowing the order
&lt;br&gt;of the datasources.
&lt;br&gt;&lt;br&gt;How is this handled in other bindings (e.g. perl) ?
&lt;br&gt;&lt;br&gt;Please tell me if I missed something obvious,
&lt;br&gt;&amp;nbsp; greetings
&lt;br&gt;&amp;nbsp; &amp;nbsp;Hermann
&lt;br&gt;&lt;br&gt;&amp;nbsp;
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; import rrdtool
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; rrdtool.__version__
&lt;br&gt;'$Revision: 1.14 $'
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; rrdtool.create('/tmp/test.rrd','--step','20','DS:ds2:GAUGE:300:0:100','DS:x1:GAUGE:300:0:100','DS:ds0:GAUGE:300:-5:100','RRA:AVERAGE:0.5:3:2')
&lt;br&gt;&amp;gt;&amp;gt;&amp;gt; rrdtool.info('/tmp/test.rrd')
&lt;br&gt;{'rra[0].cdp_prep[0].value': None, 'ds[ds2].min': 0.0, 'ds[ds0].min': -5.0, 'rra[0].cdp_prep[1].unknown_datapoints': 1L, 'ds[ds2].value': 0.0, 'ds[ds2].last_ds': 'U', 'ds[x1].max': 100.0, 'ds[ds2].unknown_sec': 5L, 'ds[ds0].value': 0.0, 'ds[ds0].unknown_sec': 5L, 'ds[ds0].max': 100.0, 'ds[ds2].max': 100.0, 'rrd_version': '0003', 'filename': '/tmp/test.rrd', 'last_update': 1256646805L, 'rra[0].cf': 'AVERAGE', 'ds[x1].type': 'GAUGE', 'rra[0].pdp_per_row': 3L, 'rra[0].cur_row': 1L, 'header_size': 1172L, 'ds[ds0].last_ds': 'U', 'step': 20L, 'rra[0].cdp_prep[0].unknown_datapoints': 1L, 'ds[ds0].type': 'GAUGE', 'rra[0].cdp_prep[2].value': None, 'ds[x1].last_ds': 'U', 'ds[ds2].minimal_heartbeat': 300L, 'rra[0].rows': 2L, 'ds[x1].min': 0.0, 'ds[ds0].minimal_heartbeat': 300L, 'ds[x1].unknown_sec': 5L, 'rra[0].xff': 0.5, 'rra[0].cdp_prep[2].unknown_datapoints': 1L, 'ds[ds2].type': 'GAUGE', 'rra[0].cdp_prep[1].value': None, 'ds[x1].value': 0.0, 'ds[x1].minimal_heartbeat': 300L}
&lt;br&gt;&amp;nbsp;
&lt;br&gt;-- 
&lt;br&gt;Netzwerkadministration/Zentrale Dienste, Interdiziplinaeres 
&lt;br&gt;Zentrum fuer wissenschaftliches Rechnen der Universitaet Heidelberg
&lt;br&gt;IWR; INF 368; 69120 Heidelberg; Tel: (06221)54-8236 Fax: -5224
&lt;br&gt;Email: &lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26078900&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;Hermann.Lauer@...&lt;/a&gt;
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26078900&amp;i=1&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/No-ordering-information-in-info-hash-tp26078900p26078900.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26076006</id>
	<title>Re: rrdtool 1.3.8: RRDs::update do no update mtime RHEL 5.1 (Tikanga) ??</title>
	<published>2009-10-27T04:20:01Z</published>
	<updated>2009-10-27T04:20:01Z</updated>
	<author>
		<name>Bernhard Reutner-Fischer</name>
	</author>
	<content type="html">On Tue, Oct 27, 2009 at 12:04:29PM +0100, Ole Bj�rn Hessen wrote:
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;Hello,
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;I've compiled rrdtool 1.3.8 on an Linux RHEL 5.1 (Tikanga) kernel
&lt;br&gt;&amp;gt;version 2.6.18-92.1.18.el5 out of the box using only the --prefix
&lt;br&gt;&amp;gt;option.
&lt;br&gt;&lt;br&gt;&amp;gt;There are no fancy mount options - just a simple ext3 rw.
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;batch-rrd4(root) ~ 724# mount | grep batch-rrd4
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;/dev/mapper/vg00-rrd on /export/batch-rrd4 type ext3 (rw)
&lt;br&gt;&amp;gt; &amp;nbsp; &amp;nbsp;/export/batch-rrd4 on /local/net/mnt/batch-rrd4 type none (rw,bind)
&lt;br&gt;&amp;gt;
&lt;br&gt;&amp;gt;Is this a simple linux bug on an RHEL 5.1 &amp;quot;old kernel&amp;quot; ?
&lt;br&gt;&lt;br&gt;This is a known bug on (old) redhat kernels, but configure should have
&lt;br&gt;detected this bug and enabled a workaround. See (just a guess):
&lt;br&gt;$ grep -A5 -B5 mmap config.log
&lt;br&gt;&lt;br&gt;It should show a probe for buggy mmap behaviour not updating mtime..
&lt;br&gt;&lt;br&gt;PS: IIRC 1.3.9 was released recently and contains some bugfixes, so i
&lt;br&gt;recommend you use that if you compile it anyway.
&lt;br&gt;&lt;br&gt;HTH,
&lt;br&gt;&lt;br&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26076006&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/rrdtool-1.3.8%3A-RRDs%3A%3Aupdate-do-no-update-mtime-RHEL-5.1-%28Tikanga%29----tp26075856p26076006.html" />
</entry>

<entry>
	<id>tag:old.nabble.com,2006:post-26075856</id>
	<title>rrdtool 1.3.8: RRDs::update do no update mtime RHEL 5.1 (Tikanga) ??</title>
	<published>2009-10-27T04:04:29Z</published>
	<updated>2009-10-27T04:04:29Z</updated>
	<author>
		<name>Ole Bjørn Hessen</name>
	</author>
	<content type="html">&lt;br&gt;Hello,
&lt;br&gt;&lt;br&gt;I've compiled rrdtool 1.3.8 on an Linux RHEL 5.1 (Tikanga) kernel
&lt;br&gt;version 2.6.18-92.1.18.el5 out of the box using only the --prefix
&lt;br&gt;option.
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |rrdtool config.status 1.3.8
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; |configured by ./configure, generated by GNU Autoconf 2.63,
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | &amp;nbsp;with options \&amp;quot;'--prefix=/local/net/arch/linux_x86_64/encap/rrdtool-1.3.8'\&amp;quot;
&lt;br&gt;&lt;br&gt;Unfortunately, it seems like mtime does not get updated. 
&lt;br&gt;&lt;br&gt;ls(1) reports that files was last updated on &amp;quot;Oct 16 09:30&amp;quot; but strace
&lt;br&gt;shows that the files is beeing updated. Also rrdtool fetch shows that
&lt;br&gt;the content has been updated. The problem seems to be that mtime is not
&lt;br&gt;updated.
&lt;br&gt;&lt;br&gt;An example file /export/batch-rrd4/interface/54/14654.rrd
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ls -slt /export/batch-rrd4/interface/54/14654.rrd
&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;6376 -rw-rw-r-- 1 tiadm tiadm 6515984 Oct 16 09:30 /export/batch-rrd4/interface/54/14654.rrd
&lt;br&gt;strace -tt:
&lt;br&gt;&lt;br&gt;11:45:09.732496 stat(&amp;quot;/export/batch-rrd4/interface/54/14654.rrd&amp;quot;, {st_mode=S_IFREG|0664, st_size=6515984, ...}) = 0
&lt;br&gt;11:45:09.732586 open(&amp;quot;/export/batch-rrd4/interface/54/14654.rrd&amp;quot;, O_RDWR) = 7
&lt;br&gt;11:45:09.732637 fstat(7, {st_mode=S_IFREG|0664, st_size=6515984, ...}) = 0
&lt;br&gt;11:45:09.732697 fadvise64(7, 0, 0, POSIX_FADV_RANDOM) = 0
&lt;br&gt;11:45:09.732737 mmap(NULL, 6515984, PROT_READ|PROT_WRITE, MAP_SHARED, 7, 0) = 0x2aaab05a4000
&lt;br&gt;11:45:09.732780 madvise(0x2aaab05a4000, 6515984, 0x1 /* MADV_??? */) = 0
&lt;br&gt;11:45:09.732819 madvise(0x2aaab05a4000, 128, MADV_SEQUENTIAL|0x1) = 0
&lt;br&gt;11:45:09.732862 madvise(0x2aaab05a4000, 7680, MADV_SEQUENTIAL|0x1) = 0
&lt;br&gt;11:45:09.732900 madvise(0x2aaab05a5000, 600, MADV_SEQUENTIAL|0x1) = 0
&lt;br&gt;11:45:09.732938 madvise(0x2aaab05a6000, 16, MADV_SEQUENTIAL|0x1) = 0
&lt;br&gt;11:45:09.732982 fcntl(7, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}) = 0
&lt;br&gt;11:45:09.733136 msync(0x2aaab05a4000, 6515984, MS_ASYNC) = 0
&lt;br&gt;11:45:09.733174 munmap(0x2aaab05a4000, 6515984) = 0
&lt;br&gt;11:45:09.733219 close(7) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= 0
&lt;br&gt;&lt;br&gt;There are no fancy mount options - just a simple ext3 rw.
&lt;br&gt;&lt;br&gt;&amp;nbsp; &amp;nbsp; batch-rrd4(root) ~ 724# mount | grep batch-rrd4
&lt;br&gt;&amp;nbsp; &amp;nbsp; /dev/mapper/vg00-rrd on /export/batch-rrd4 type ext3 (rw)
&lt;br&gt;&amp;nbsp; &amp;nbsp; /export/batch-rrd4 on /local/net/mnt/batch-rrd4 type none (rw,bind)
&lt;br&gt;&lt;br&gt;Is this a simple linux bug on an RHEL 5.1 &amp;quot;old kernel&amp;quot; ?
&lt;br&gt;&lt;br&gt;Ole Bjørn Hessen,
&lt;br&gt;NMS-IP
&lt;br&gt;Telenor
&lt;br&gt;&lt;br&gt;&lt;br /&gt;_______________________________________________
&lt;br&gt;rrd-developers mailing list
&lt;br&gt;&lt;a href=&quot;http://old.nabble.com/user/SendEmail.jtp?type=post&amp;post=26075856&amp;i=0&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;rrd-developers@...&lt;/a&gt;
&lt;br&gt;&lt;a href=&quot;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&quot; target=&quot;_top&quot; rel=&quot;nofollow&quot;&gt;https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers&lt;/a&gt;&lt;br&gt;</content>
	<link rel="alternate" type="text/html" href="http://old.nabble.com/rrdtool-1.3.8%3A-RRDs%3A%3Aupdate-do-no-update-mtime-RHEL-5.1-%28Tikanga%29----tp26075856p26075856.html" />
</entry>

</feed>
