util: util_ntdb ntdb_fetch_int32/ntdb_store_int32 and ntdb_add_int32_atomic
authorRusty Russell <rusty@rustcorp.com.au>
Fri, 22 Jun 2012 00:14:42 +0000 (09:44 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Fri, 22 Jun 2012 05:35:17 +0000 (07:35 +0200)
Similar to the util_tdb versions, but return the error code.

ntdb_add_int32_atomic seems a clearer name than tdb_change_int32_atomic.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
lib/util/util_ntdb.c
lib/util/util_ntdb.h

index ad9e0a73d20c06b78851413813b424c9394e2a8e..be720e55a6c14847ee900e1540e22b12eabb541c 100644 (file)
@@ -237,6 +237,71 @@ enum NTDB_ERROR ntdb_fetch_bystring(struct ntdb_context *ntdb,
        return ntdb_fetch(ntdb, key, data);
 }
 
+enum NTDB_ERROR ntdb_fetch_int32(struct ntdb_context *ntdb,
+                                const char *keystr, int32_t *val)
+{
+       NTDB_DATA data;
+       enum NTDB_ERROR err;
+
+       err = ntdb_fetch(ntdb, string_term_ntdb_data(keystr), &data);
+       if (err == NTDB_SUCCESS) {
+               if (data.dsize != sizeof(*val)) {
+                       err = NTDB_ERR_CORRUPT;
+               } else {
+                       *val = IVAL(data.dptr,0);
+               }
+               talloc_free(data.dptr);
+       }
+       return NTDB_SUCCESS;
+}
+
+enum NTDB_ERROR ntdb_store_int32(struct ntdb_context *ntdb,
+                                const char *keystr, int32_t val)
+{
+       NTDB_DATA data, key;
+       int32_t v_store;
+
+       SIVAL(&v_store, 0, val);
+       data = ntdb_mkdata(&v_store, sizeof(v_store));
+       key = string_term_ntdb_data(keystr);
+
+       return ntdb_store(ntdb, key, data, NTDB_REPLACE);
+}
+
+enum NTDB_ERROR ntdb_add_int32_atomic(struct ntdb_context *ntdb,
+                                     const char *keystr,
+                                     int32_t *oldval, int32_t addval)
+{
+       int32_t val;
+       enum NTDB_ERROR err;
+
+       err = ntdb_lock_bystring(ntdb, keystr);
+       if (err) {
+               return err;
+       }
+
+       err = ntdb_fetch_int32(ntdb, keystr, &val);
+       if (err) {
+               if (err == NTDB_ERR_NOEXIST) {
+                       /* Start with 'old' value */
+                       val = *oldval;
+               } else {
+                       goto err_out;
+               }
+       } else {
+               /* It worked, set return value (oldval) to tdb data */
+               *oldval = val;
+       }
+
+       /* Increase value and store for next time. */
+       val += addval;
+       err = ntdb_store_int32(ntdb, keystr, val);
+
+  err_out:
+       ntdb_unlock_bystring(ntdb, keystr);
+       return err;
+}
+
 NTSTATUS map_nt_error_from_ntdb(enum NTDB_ERROR err)
 {
        NTSTATUS result = NT_STATUS_INTERNAL_ERROR;
index eac0db4f027d8e9533b9419064b14cab4c62eed5..7531c42dee8bfe33b5fdf567583b737654168e5b 100644 (file)
@@ -95,6 +95,30 @@ enum NTDB_ERROR ntdb_fetch_bystring(struct ntdb_context *ntdb,
                                    NTDB_DATA *data);
 
 
+/****************************************************************************
+ Fetch a int32_t value by a string key.  *val is int32_t in native byte order.
+ ntdb must have been created with ntdb_new() (as it uses talloc_free).
+****************************************************************************/
+enum NTDB_ERROR ntdb_fetch_int32(struct ntdb_context *ntdb,
+                                const char *keystr, int32_t *val);
+
+/****************************************************************************
+ Store a int32_t value by a string key.  val is int32_t in native byte order.
+****************************************************************************/
+enum NTDB_ERROR ntdb_store_int32(struct ntdb_context *ntdb,
+                                const char *keystr, int32_t val);
+
+
+/****************************************************************************
+ Atomic integer add; reads the old value into *oldval (if found), then stores
+ *oldval + addval back for next time.  Uses chainlock to do this atomically.
+
+ Thus the first time this is ever called, oldval will be unchanged.
+****************************************************************************/
+enum NTDB_ERROR ntdb_add_int32_atomic(struct ntdb_context *ntdb,
+                                     const char *keystr,
+                                     int32_t *oldval, int32_t addval);
+
 /****************************************************************************
  Turn a nul-terminated string into an NTDB_DATA.
 ****************************************************************************/