]> git.sur5r.net Git - openldap/commitdiff
adaptive caching code
authorJong Hyuk Choi <jongchoi@openldap.org>
Tue, 14 Dec 2004 17:25:35 +0000 (17:25 +0000)
committerJong Hyuk Choi <jongchoi@openldap.org>
Tue, 14 Dec 2004 17:25:35 +0000 (17:25 +0000)
servers/slapd/entry.c
servers/slapd/proto-slap.h
servers/slapd/slap.h
servers/slapd/zn_malloc.c

index 5d238d03287a410e94bd54bef5c3c17cbff4b811..13fee4fc2872975a9d868ad076fcaca123da37a4 100644 (file)
@@ -596,7 +596,11 @@ int entry_encode(Entry *e, struct berval *bv)
  * you can not free individual attributes or names from this
  * structure. Attempting to do so will likely corrupt memory.
  */
+#ifdef SLAP_ZONE_ALLOC
+int entry_decode(struct berval *bv, Entry **e, void *ctx)
+#else
 int entry_decode(struct berval *bv, Entry **e)
+#endif
 {
        int i, j, count;
        int rc;
@@ -613,7 +617,15 @@ int entry_decode(struct berval *bv, Entry **e)
                        "entry_decode: entry length was zero\n", 0, 0, 0);
                return LDAP_OTHER;
        }
+#ifdef SLAP_ZONE_ALLOC
+       x = slap_zn_calloc(1, i + bv->bv_len, ctx);
+       AC_MEMCPY((char*)x + i, bv->bv_val, bv->bv_len);
+       bv->bv_val = (char*)x + i;
+       ptr = (unsigned char *)bv->bv_val;
+       i = entry_getlen(&ptr);
+#else
        x = ch_calloc(1, i);
+#endif
        i = entry_getlen(&ptr);
        x->e_name.bv_val = (char *) ptr;
        x->e_name.bv_len = i;
index 1aeab3f09cecf833bacd3dc1bdb4c00aa6a957d8..9237cc7629c8acefeb512d25503d3378b722363d 100644 (file)
@@ -620,7 +620,13 @@ LDAP_SLAPD_F (char *) entry2str LDAP_P(( Entry *e, int *len ));
 
 LDAP_SLAPD_F (void) entry_flatsize LDAP_P((
        Entry *e, ber_len_t *siz, ber_len_t *len, int norm ));
-LDAP_SLAPD_F (int) entry_decode LDAP_P(( struct berval *bv, Entry **e ));
+#ifdef SLAP_ZONE_ALLOC
+LDAP_SLAPD_F (int) entry_decode LDAP_P((
+                                               struct berval *bv, Entry **e, void *ctx ));
+#else
+LDAP_SLAPD_F (int) entry_decode LDAP_P((
+                                               struct berval *bv, Entry **e ));
+#endif
 LDAP_SLAPD_F (int) entry_encode LDAP_P(( Entry *e, struct berval *bv ));
 
 LDAP_SLAPD_F (void) entry_clean LDAP_P(( Entry *e ));
@@ -1342,6 +1348,30 @@ LDAP_SLAPD_F (int) value_add_one LDAP_P((
 /* assumes (x) > (y) returns 1 if true, 0 otherwise */
 #define SLAP_PTRCMP(x, y) ((x) < (y) ? -1 : (x) > (y))
 
+#ifdef SLAP_ZONE_ALLOC
+/*
+ * zn_malloc.c
+ */
+LDAP_SLAPD_F (void *) slap_zn_malloc LDAP_P((ber_len_t, void *));
+LDAP_SLAPD_F (void *) slap_zn_realloc LDAP_P((void *, ber_len_t, void *));
+LDAP_SLAPD_F (void *) slap_zn_calloc LDAP_P((ber_len_t, ber_len_t, void *));
+LDAP_SLAPD_F (void) slap_zn_free LDAP_P((void *, void *));
+
+LDAP_SLAPD_F (void *) slap_zn_mem_create LDAP_P((
+                                                       ber_len_t, ber_len_t, ber_len_t, ber_len_t));
+LDAP_SLAPD_F (void) slap_zn_mem_destroy LDAP_P((void *));
+LDAP_SLAPD_F (int) slap_zn_validate LDAP_P((void *, void *, int));
+LDAP_SLAPD_F (int) slap_zn_invalidate LDAP_P((void *, void *));
+LDAP_SLAPD_F (int) slap_zh_rlock LDAP_P((void*));
+LDAP_SLAPD_F (int) slap_zh_runlock LDAP_P((void*));
+LDAP_SLAPD_F (int) slap_zh_wlock LDAP_P((void*));
+LDAP_SLAPD_F (int) slap_zh_wunlock LDAP_P((void*));
+LDAP_SLAPD_F (int) slap_zn_rlock LDAP_P((void*, void*));
+LDAP_SLAPD_F (int) slap_zn_runlock LDAP_P((void*, void*));
+LDAP_SLAPD_F (int) slap_zn_wlock LDAP_P((void*, void*));
+LDAP_SLAPD_F (int) slap_zn_wunlock LDAP_P((void*, void*));
+#endif
+
 /*
  * Other...
  */
index 785f72cf595a38c884ee001487305cca604258fd..3dd62fcfddb6e664271201baf782aa8e787eb18a 100644 (file)
@@ -2860,6 +2860,7 @@ struct slab_heap {
 #define SLAP_ZONE_SIZE 0x80000         /* 512KB */
 #define SLAP_ZONE_SHIFT 19
 #define SLAP_ZONE_INITSIZE 0x800000 /* 8MB */
+#define SLAP_ZONE_MAXSIZE 0x80000000/* 2GB */
 #define SLAP_ZONE_DELTA 0x800000       /* 8MB */
 #define SLAP_ZONE_ZOBLOCK 256
 
@@ -2871,6 +2872,11 @@ struct zone_object {
        LDAP_LIST_ENTRY(zone_object) zo_link;
 };
 
+struct zone_latency_history {
+       double zlh_latency;
+       LDAP_STAILQ_ENTRY(zone_latency_history) zlh_next;
+};
+
 struct zone_heap {
        int zh_fd;
        int zh_zonesize;
@@ -2887,6 +2893,13 @@ struct zone_heap {
        LDAP_LIST_HEAD( zh_so, zone_object ) zh_zopool;
        ldap_pvt_thread_mutex_t zh_mutex;
        ldap_pvt_thread_rdwr_t zh_lock;
+       double zh_ema_latency;
+       unsigned long zh_ema_samples;
+       LDAP_STAILQ_HEAD( zh_latency_history, zone_latency_history )
+                               zh_latency_history_queue;
+       int zh_latency_history_qlen;
+       int zh_latency_jump;
+       int zh_swapping;
 };
 #endif
 
index c2e8d20f967dbba003601d28367294d9562ec1a4..328616d19ba625670b470ac0a54e7679c8a61a2d 100644 (file)
@@ -220,6 +220,7 @@ slap_zn_mem_create(
                ldap_pvt_thread_rdwr_init(&zh->zh_znlock[i]);
        }
 
+       LDAP_STAILQ_INIT(&zh->zh_latency_history_queue);
        ldap_pvt_thread_mutex_init(&zh->zh_mutex);
        ldap_pvt_thread_rdwr_init(&zh->zh_lock);
 
@@ -892,4 +893,79 @@ int slap_zn_wunlock(
        }
 }
 
+#define T_SEC_IN_USEC 1000000
+
+static int
+slap_timediff(struct timeval *tv_begin, struct timeval *tv_end)
+{
+       uint64_t t_begin, t_end, t_diff;
+
+       t_begin = T_SEC_IN_USEC * tv_begin->tv_sec + tv_begin->tv_usec;
+       t_end  = T_SEC_IN_USEC * tv_end->tv_sec  + tv_end->tv_usec;
+       t_diff  = t_end - t_begin;
+       
+       if ( t_diff < 0 )
+               t_diff = 0;
+
+       return (int)t_diff;
+}
+
+void
+slap_set_timing(struct timeval *tv_set)
+{
+       gettimeofday(tv_set, (struct timezone *)NULL);
+}
+
+int
+slap_measure_timing(struct timeval *tv_set, struct timeval *tv_measure)
+{
+       gettimeofday(tv_measure, (struct timezone *)NULL);
+       return(slap_timediff(tv_set, tv_measure));
+}
+
+#define EMA_WEIGHT 0.999000
+#define SLAP_ZN_LATENCY_HISTORY_QLEN 500
+int
+slap_zn_latency_history(void* ctx, int ea_latency)
+{
+/* TODO: monitor /proc/swap as well */
+       struct zone_heap* zh = ctx;
+       double t_diff = 0.0;
+
+       zh->zh_ema_latency = (double)ea_latency * (1.0 - EMA_WEIGHT)
+                                       + zh->zh_ema_latency * EMA_WEIGHT;
+       if (!zh->zh_swapping && zh->zh_ema_samples++ % 100 == 99) {
+               struct zone_latency_history *zlh_entry;
+               zlh_entry = ch_calloc(1, sizeof(struct zone_latency_history));
+               zlh_entry->zlh_latency = zh->zh_ema_latency;
+               LDAP_STAILQ_INSERT_TAIL(
+                               &zh->zh_latency_history_queue, zlh_entry, zlh_next);
+               zh->zh_latency_history_qlen++;
+               while (zh->zh_latency_history_qlen > SLAP_ZN_LATENCY_HISTORY_QLEN) {
+                       struct zone_latency_history *zlh;
+                       zlh = LDAP_STAILQ_FIRST(&zh->zh_latency_history_queue);
+                       LDAP_STAILQ_REMOVE_HEAD(
+                                       &zh->zh_latency_history_queue, zlh_next);
+                       zh->zh_latency_history_qlen--;
+                       ch_free(zlh);
+               }
+               if (zh->zh_latency_history_qlen == SLAP_ZN_LATENCY_HISTORY_QLEN) {
+                       struct zone_latency_history *zlh_first, *zlh_last;
+                       zlh_first = LDAP_STAILQ_FIRST(&zh->zh_latency_history_queue);
+                       zlh_last = LDAP_STAILQ_LAST(&zh->zh_latency_history_queue,
+                                               zone_latency_history, zlh_next);
+                       t_diff = zlh_last->zlh_latency - zlh_first->zlh_latency;
+               }
+               if (t_diff >= 2000) {
+                       zh->zh_latency_jump++;
+               } else {
+                       zh->zh_latency_jump = 0;
+               }
+               if (zh->zh_latency_jump > 3) {
+                       zh->zh_latency_jump = 0;
+                       zh->zh_swapping = 1;
+               }
+       }
+       return zh->zh_swapping;
+}
 #endif /* SLAP_ZONE_ALLOC */