Changeset: 5045fa574e24 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/5045fa574e24
Branch: default
Log Message:

Merge strheapvacuum branch into default.


diffs (truncated from 955 to 300 lines):

diff --git a/clients/Tests/MAL-signatures.stable.out 
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -637,6 +637,7 @@
 [ "bat",       "getRole",      "command bat.getRole(X_0:bat[:any_1]):str ",    
"BKCgetRole;",  "Returns the rolename of the head column of a BAT."     ]
 [ "bat",       "getSequenceBase",      "command 
bat.getSequenceBase(X_0:bat[:any_1]):oid ",    "BKCgetSequenceBase;",  "Get the 
sequence base for the void column of a BAT."   ]
 [ "bat",       "getSize",      "command bat.getSize(X_0:bat[:any_1]):lng ",    
"BKCgetSize;",  "Calculate the actual size of the BAT descriptor, heaps, hashes 
and imprint indices in bytes\nrounded to the memory page size (see 
bbp.getPageSize())." ]
+[ "bat",       "getVHeapSize", "command bat.getVHeapSize(X_0:bat[:any_1]):lng 
",       "BKCgetVHeapSize;",     "Calculate the vheap size for string bats"     
 ]
 [ "bat",       "getorderidx",  "pattern 
bat.getorderidx(X_0:bat[:any_1]):bat[:oid] ",  "OIDXgetorderidx;",     "Return 
the order index if it exists"   ]
 [ "bat",       "hasorderidx",  "pattern bat.hasorderidx(X_0:bat[:any_1]):bit 
",        "OIDXhasorderidx;",     "Return true if order index exists"     ]
 [ "bat",       "imprints",     "command bat.imprints(X_0:bat[:bte]):void ",    
"CMDBATimprints;",      ""      ]
@@ -689,6 +690,7 @@
 [ "bat",       "setPersistent",        "command 
bat.setPersistent(X_0:bat[:any_1]):void ",     "BKCsetPersistent;",    "Make 
the BAT persistent."      ]
 [ "bat",       "setTransient", "command bat.setTransient(X_0:bat[:any_1]):void 
",      "BKCsetTransient;",     "Make the BAT transient.  Returns \nboolean 
which indicates if the\nBAT administration has indeed changed."     ]
 [ "bat",       "single",       "pattern bat.single(X_0:any_1):bat[:any_1] ",   
"CMDBATsingle;",        "Create a BAT with a single elemenet"   ]
+[ "bat",       "vacuum",       "command bat.vacuum(X_0:bat[:str]):bat[:str] ", 
"CMDBATvacuum;",        ""      ]
 [ "bataggr",   "allnotequal",  "pattern bataggr.allnotequal(X_0:bat[:any_1], 
X_1:bat[:any_1]):bit ",   "SQLallnotequal;",      ""      ]
 [ "bataggr",   "anyequal",     "pattern bataggr.anyequal(X_0:bat[:any_1], 
X_1:bat[:any_1]):bat[:bit] ",        "SQLanyequal;", ""      ]
 [ "bataggr",   "exist",        "pattern bataggr.exist(X_0:any_1):bat[:bit] ",  
"SQLexist;",    ""      ]
@@ -9427,6 +9429,7 @@
 [ "sql",       "stdevp",       "pattern sql.stdevp(X_0:int, X_1:bit, X_2:bit, 
X_3:int, X_4:oid, X_5:oid):dbl ",        "SQLstddev_pop;",       "return the 
standard deviation population of groups"    ]
 [ "sql",       "stdevp",       "pattern sql.stdevp(X_0:lng, X_1:bit, X_2:bit, 
X_3:int, X_4:oid, X_5:oid):dbl ",        "SQLstddev_pop;",       "return the 
standard deviation population of groups"    ]
 [ "sql",       "stdevp",       "pattern sql.stdevp(X_0:sht, X_1:bit, X_2:bit, 
X_3:int, X_4:oid, X_5:oid):dbl ",        "SQLstddev_pop;",       "return the 
standard deviation population of groups"    ]
+[ "sql",       "stop_vacuum",  "pattern sql.stop_vacuum(X_0:str, X_1:str, 
X_2:str):void ",     "SQLstr_column_stop_vacuum;",   "stop auto vacuum"      ]
 [ "sql",       "storage",      "pattern sql.storage() (X_0:bat[:str], 
X_1:bat[:str], X_2:bat[:str], X_3:bat[:str], X_4:bat[:str], X_5:bat[:str], 
X_6:bat[:lng], X_7:bat[:int], X_8:bat[:lng], X_9:bat[:lng], X_10:bat[:lng], 
X_11:bat[:bit], X_12:bat[:lng], X_13:bat[:bit], X_14:bat[:bit], X_15:bat[:bit], 
X_16:bat[:lng]) ",        "sql_storage;", "return a table with storage 
information "      ]
 [ "sql",       "storage",      "pattern sql.storage(X_0:str) (X_1:bat[:str], 
X_2:bat[:str], X_3:bat[:str], X_4:bat[:str], X_5:bat[:str], X_6:bat[:str], 
X_7:bat[:lng], X_8:bat[:int], X_9:bat[:lng], X_10:bat[:lng], X_11:bat[:lng], 
X_12:bat[:bit], X_13:bat[:lng], X_14:bat[:bit], X_15:bat[:bit], X_16:bat[:bit], 
X_17:bat[:lng]) ",        "sql_storage;", "return a table with storage 
information for a particular schema "      ]
 [ "sql",       "storage",      "pattern sql.storage(X_0:str, X_1:str) 
(X_2:bat[:str], X_3:bat[:str], X_4:bat[:str], X_5:bat[:str], X_6:bat[:str], 
X_7:bat[:str], X_8:bat[:lng], X_9:bat[:int], X_10:bat[:lng], X_11:bat[:lng], 
X_12:bat[:lng], X_13:bat[:bit], X_14:bat[:lng], X_15:bat[:bit], X_16:bat[:bit], 
X_17:bat[:bit], X_18:bat[:lng]) ",      "sql_storage;", "return a table with 
storage information for a particular table"        ]
@@ -9455,6 +9458,8 @@
 [ "sql",       "update",       "pattern sql.update(X_0:int, X_1:str, X_2:str, 
X_3:str, X_4:any, X_5:any):int ",        "mvc_update_wrap;",     "Update the 
values of the column tname.cname. Returns sequence number for order 
dependence)"    ]
 [ "sql",       "update_schemas",       "unsafe pattern 
sql.update_schemas():void ",    "SYSupdate_schemas;",   "Procedure triggered on 
update of the sys.schemas table"        ]
 [ "sql",       "update_tables",        "unsafe pattern 
sql.update_tables():void ",     "SYSupdate_tables;",    "Procedure triggered on 
update of the sys._tables table"        ]
+[ "sql",       "vacuum",       "pattern sql.vacuum(X_0:str, X_1:str, X_2:str, 
X_3:int):void ", "SQLstr_column_auto_vacuum;",   "auto vacuum string column 
with interval(sec)"  ]
+[ "sql",       "vacuum",       "pattern sql.vacuum(X_0:str, X_1:str, 
X_2:str):void ",  "SQLstr_column_vacuum;",        "vacuum a string column"      
  ]
 [ "sql",       "variance",     "pattern sql.variance(X_0:bte, X_1:bit, 
X_2:bit, X_3:int, X_4:oid, X_5:oid):dbl ",      "SQLvar_samp;", "return the 
variance sample of groups"  ]
 [ "sql",       "variance",     "pattern sql.variance(X_0:dbl, X_1:bit, 
X_2:bit, X_3:int, X_4:oid, X_5:oid):dbl ",      "SQLvar_samp;", "return the 
variance sample of groups"  ]
 [ "sql",       "variance",     "pattern sql.variance(X_0:flt, X_1:bit, 
X_2:bit, X_3:int, X_4:oid, X_5:oid):dbl ",      "SQLvar_samp;", "return the 
variance sample of groups"  ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128 
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -750,6 +750,7 @@
 [ "bat",       "getRole",      "command bat.getRole(X_0:bat[:any_1]):str ",    
"BKCgetRole;",  "Returns the rolename of the head column of a BAT."     ]
 [ "bat",       "getSequenceBase",      "command 
bat.getSequenceBase(X_0:bat[:any_1]):oid ",    "BKCgetSequenceBase;",  "Get the 
sequence base for the void column of a BAT."   ]
 [ "bat",       "getSize",      "command bat.getSize(X_0:bat[:any_1]):lng ",    
"BKCgetSize;",  "Calculate the actual size of the BAT descriptor, heaps, hashes 
and imprint indices in bytes\nrounded to the memory page size (see 
bbp.getPageSize())." ]
+[ "bat",       "getVHeapSize", "command bat.getVHeapSize(X_0:bat[:any_1]):lng 
",       "BKCgetVHeapSize;",     "Calculate the vheap size for string bats"     
 ]
 [ "bat",       "getorderidx",  "pattern 
bat.getorderidx(X_0:bat[:any_1]):bat[:oid] ",  "OIDXgetorderidx;",     "Return 
the order index if it exists"   ]
 [ "bat",       "hasorderidx",  "pattern bat.hasorderidx(X_0:bat[:any_1]):bit 
",        "OIDXhasorderidx;",     "Return true if order index exists"     ]
 [ "bat",       "imprints",     "command bat.imprints(X_0:bat[:bte]):void ",    
"CMDBATimprints;",      ""      ]
@@ -804,6 +805,7 @@
 [ "bat",       "setPersistent",        "command 
bat.setPersistent(X_0:bat[:any_1]):void ",     "BKCsetPersistent;",    "Make 
the BAT persistent."      ]
 [ "bat",       "setTransient", "command bat.setTransient(X_0:bat[:any_1]):void 
",      "BKCsetTransient;",     "Make the BAT transient.  Returns \nboolean 
which indicates if the\nBAT administration has indeed changed."     ]
 [ "bat",       "single",       "pattern bat.single(X_0:any_1):bat[:any_1] ",   
"CMDBATsingle;",        "Create a BAT with a single elemenet"   ]
+[ "bat",       "vacuum",       "command bat.vacuum(X_0:bat[:str]):bat[:str] ", 
"CMDBATvacuum;",        ""      ]
 [ "bataggr",   "allnotequal",  "pattern bataggr.allnotequal(X_0:bat[:any_1], 
X_1:bat[:any_1]):bit ",   "SQLallnotequal;",      ""      ]
 [ "bataggr",   "anyequal",     "pattern bataggr.anyequal(X_0:bat[:any_1], 
X_1:bat[:any_1]):bat[:bit] ",        "SQLanyequal;", ""      ]
 [ "bataggr",   "exist",        "pattern bataggr.exist(X_0:any_1):bat[:bit] ",  
"SQLexist;",    ""      ]
@@ -12739,6 +12741,7 @@
 [ "sql",       "stdevp",       "pattern sql.stdevp(X_0:int, X_1:bit, X_2:bit, 
X_3:int, X_4:oid, X_5:oid):dbl ",        "SQLstddev_pop;",       "return the 
standard deviation population of groups"    ]
 [ "sql",       "stdevp",       "pattern sql.stdevp(X_0:lng, X_1:bit, X_2:bit, 
X_3:int, X_4:oid, X_5:oid):dbl ",        "SQLstddev_pop;",       "return the 
standard deviation population of groups"    ]
 [ "sql",       "stdevp",       "pattern sql.stdevp(X_0:sht, X_1:bit, X_2:bit, 
X_3:int, X_4:oid, X_5:oid):dbl ",        "SQLstddev_pop;",       "return the 
standard deviation population of groups"    ]
+[ "sql",       "stop_vacuum",  "pattern sql.stop_vacuum(X_0:str, X_1:str, 
X_2:str):void ",     "SQLstr_column_stop_vacuum;",   "stop auto vacuum"      ]
 [ "sql",       "storage",      "pattern sql.storage() (X_0:bat[:str], 
X_1:bat[:str], X_2:bat[:str], X_3:bat[:str], X_4:bat[:str], X_5:bat[:str], 
X_6:bat[:lng], X_7:bat[:int], X_8:bat[:lng], X_9:bat[:lng], X_10:bat[:lng], 
X_11:bat[:bit], X_12:bat[:lng], X_13:bat[:bit], X_14:bat[:bit], X_15:bat[:bit], 
X_16:bat[:lng]) ",        "sql_storage;", "return a table with storage 
information "      ]
 [ "sql",       "storage",      "pattern sql.storage(X_0:str) (X_1:bat[:str], 
X_2:bat[:str], X_3:bat[:str], X_4:bat[:str], X_5:bat[:str], X_6:bat[:str], 
X_7:bat[:lng], X_8:bat[:int], X_9:bat[:lng], X_10:bat[:lng], X_11:bat[:lng], 
X_12:bat[:bit], X_13:bat[:lng], X_14:bat[:bit], X_15:bat[:bit], X_16:bat[:bit], 
X_17:bat[:lng]) ",        "sql_storage;", "return a table with storage 
information for a particular schema "      ]
 [ "sql",       "storage",      "pattern sql.storage(X_0:str, X_1:str) 
(X_2:bat[:str], X_3:bat[:str], X_4:bat[:str], X_5:bat[:str], X_6:bat[:str], 
X_7:bat[:str], X_8:bat[:lng], X_9:bat[:int], X_10:bat[:lng], X_11:bat[:lng], 
X_12:bat[:lng], X_13:bat[:bit], X_14:bat[:lng], X_15:bat[:bit], X_16:bat[:bit], 
X_17:bat[:bit], X_18:bat[:lng]) ",      "sql_storage;", "return a table with 
storage information for a particular table"        ]
@@ -12772,6 +12775,8 @@
 [ "sql",       "update",       "pattern sql.update(X_0:int, X_1:str, X_2:str, 
X_3:str, X_4:any, X_5:any):int ",        "mvc_update_wrap;",     "Update the 
values of the column tname.cname. Returns sequence number for order 
dependence)"    ]
 [ "sql",       "update_schemas",       "unsafe pattern 
sql.update_schemas():void ",    "SYSupdate_schemas;",   "Procedure triggered on 
update of the sys.schemas table"        ]
 [ "sql",       "update_tables",        "unsafe pattern 
sql.update_tables():void ",     "SYSupdate_tables;",    "Procedure triggered on 
update of the sys._tables table"        ]
+[ "sql",       "vacuum",       "pattern sql.vacuum(X_0:str, X_1:str, X_2:str, 
X_3:int):void ", "SQLstr_column_auto_vacuum;",   "auto vacuum string column 
with interval(sec)"  ]
+[ "sql",       "vacuum",       "pattern sql.vacuum(X_0:str, X_1:str, 
X_2:str):void ",  "SQLstr_column_vacuum;",        "vacuum a string column"      
  ]
 [ "sql",       "variance",     "pattern sql.variance(X_0:bte, X_1:bit, 
X_2:bit, X_3:int, X_4:oid, X_5:oid):dbl ",      "SQLvar_samp;", "return the 
variance sample of groups"  ]
 [ "sql",       "variance",     "pattern sql.variance(X_0:dbl, X_1:bit, 
X_2:bit, X_3:int, X_4:oid, X_5:oid):dbl ",      "SQLvar_samp;", "return the 
variance sample of groups"  ]
 [ "sql",       "variance",     "pattern sql.variance(X_0:flt, X_1:bit, 
X_2:bit, X_3:int, X_4:oid, X_5:oid):dbl ",      "SQLvar_samp;", "return the 
variance sample of groups"  ]
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -1252,7 +1252,6 @@ gdk_export BAT *COLcopy(BAT *b, int tt, 
 
 gdk_export gdk_return BATgroup(BAT **groups, BAT **extents, BAT **histo, BAT 
*b, BAT *s, BAT *g, BAT *e, BAT *h)
        __attribute__((__warn_unused_result__));
-
 /*
  * @- BAT Input/Output
  * @multitable @columnfractions 0.08 0.7
@@ -2381,4 +2380,20 @@ gdk_export BAT *BATsample_with_seed(BAT 
                        CALLBACK;               \
        } while (0)
 
+typedef struct gdk_callback {
+       char *name;
+       int argc;
+       int interval;  // units sec
+       lng last_called; // timestamp GDKusec
+       gdk_return (*func)(int argc, void *argv[]);
+       struct gdk_callback *next;
+       void *argv[FLEXIBLE_ARRAY_MEMBER];
+} gdk_callback;
+
+typedef gdk_return gdk_callback_func(int argc, void *argv[]);
+
+gdk_export gdk_return gdk_add_callback(char *name, gdk_callback_func *f, int 
argc, void
+               *argv[], int interval);
+gdk_export gdk_return gdk_remove_callback(char *, gdk_callback_func *f);
+
 #endif /* _GDK_H_ */
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -2787,3 +2787,4 @@ BATassertProps(BAT *b)
        }
        MT_lock_unset(&b->theaplock);
 }
+
diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -130,6 +130,7 @@ static gdk_return BBPprepare(bool subcom
 static BAT *getBBPdescriptor(bat i, bool lock);
 static gdk_return BBPbackup(BAT *b, bool subcommit);
 static gdk_return BBPdir_init(void);
+static void BBPcallbacks(void);
 
 static lng BBPlogno;           /* two lngs of extra info in BBP.dir */
 static lng BBPtransid;
@@ -1404,6 +1405,7 @@ BBPmanager(void *dummy)
                                return;
                }
                BBPtrim(false);
+               BBPcallbacks();
                if (GDKexiting())
                        return;
        }
@@ -4306,3 +4308,129 @@ gdk_bbp_reset(void)
        backup_dir = 0;
        backup_subdir = 0;
 }
+
+static MT_Lock GDKCallbackListLock = MT_LOCK_INITIALIZER(GDKCallbackListLock);
+
+static struct {
+       int cnt;
+       gdk_callback *head;
+} callback_list = {
+       .cnt = 0,
+       .head = NULL,
+};
+
+/*
+ * @- Add a callback
+ * Adds new callback to the callback list.
+ */
+gdk_return
+gdk_add_callback(char *name, gdk_callback_func *f, int argc, void *argv[], int
+               interval)
+{
+
+       gdk_callback *callback = NULL;
+       gdk_callback *p = callback_list.head;
+
+       if (!(callback = GDKmalloc(sizeof(gdk_callback) + sizeof(void *) * 
argc))) {
+               TRC_CRITICAL(GDK, "Failed to allocate memory!");
+               return GDK_FAIL;
+       }
+
+       *callback = (gdk_callback) {
+               .name = name,
+               .argc = argc,
+               .interval = interval,
+               .func = f,
+       };
+
+       for (int i=0; i < argc; i++) {
+               callback->argv[i] = argv[i];
+       }
+
+       MT_lock_set(&GDKCallbackListLock);
+       if (p) {
+               int cnt = 1;
+               do {
+                       // check if already added
+                       if (strcmp(callback->name, p->name) == 0)
+                               return GDK_FAIL;
+                       if (p->next == NULL) {
+                               p->next = callback;
+                               p = callback->next;
+                       } else {
+                               p = p->next;
+                       }
+                       cnt += 1;
+               } while(p);
+               callback_list.cnt = cnt;
+       } else {
+               callback_list.cnt = 1;
+               callback_list.head = callback;
+       }
+       MT_lock_unset(&GDKCallbackListLock);
+       return GDK_SUCCEED;
+}
+
+/*
+ * @- Remove a callback
+ * Removes a callback from the callback list with a given name as an argument.
+ */
+gdk_return
+gdk_remove_callback(char *cb_name, gdk_callback_func *argsfree)
+{
+       gdk_callback *curr = callback_list.head;
+       gdk_callback *prev = NULL;
+       gdk_return res = GDK_FAIL;
+       while(curr) {
+               if (strcmp(cb_name, curr->name) == 0) {
+                       MT_lock_set(&GDKCallbackListLock);
+                       if (curr == callback_list.head && prev == NULL) {
+                               callback_list.head = curr->next;
+                       } else {
+                               prev->next = curr->next;
+                       }
+                       if (argsfree)
+                               argsfree(curr->argc, curr->argv);
+                       GDKfree(curr);
+                       curr = NULL;
+                       callback_list.cnt -=1;
+                       res = GDK_SUCCEED;
+                       MT_lock_unset(&GDKCallbackListLock);
+               } else {
+                       prev = curr;
+                       curr = curr->next;
+               }
+       }
+       return res;
+}
+
+static gdk_return
+do_callback(gdk_callback *cb)
+{
+       cb->last_called = GDKusec();
+       return cb->func(cb->argc, cb->argv);
+}
+
+static bool
+should_call(gdk_callback *cb)
+{
+       if (cb->last_called && cb->interval) {
+               return (cb->last_called + cb->interval * 1000 * 1000) <
+                       GDKusec();
+       }
+       return true;
+}
+
+static void
+BBPcallbacks(void)
+{
+       gdk_callback *next = callback_list.head;
+
+       MT_lock_set(&GDKCallbackListLock);
+       while (next) {
+               if(should_call(next))
+                       do_callback(next);
+               next = next->next;
+       }
+       MT_lock_unset(&GDKCallbackListLock);
+}
diff --git a/monetdb5/modules/kernel/bat5.c b/monetdb5/modules/kernel/bat5.c
--- a/monetdb5/modules/kernel/bat5.c
+++ b/monetdb5/modules/kernel/bat5.c
@@ -611,6 +611,23 @@ BKCgetSize(lng *tot, const bat *bid){
        return MAL_SUCCEED;
 }
 
+static str
+BKCgetVHeapSize(lng *tot, const bat *bid){
+       BAT *b;
+       lng size = 0;
+       if ((b = BATdescriptor(*bid)) == NULL) {
+               throw(MAL, "bat.getVHeapSize", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
+       }
+       int _tpe= ATOMstorage((b)->ttype);
+       if (_tpe >= TYPE_str) {
+               size += b->tvheap->size;
+       }
+
+       *tot = size;
+       BBPunfix(*bid);
+       return MAL_SUCCEED;
+}
+
 /*
  * Synced BATs
  */
@@ -1234,6 +1251,7 @@ mel_func bat5_init_funcs[] = {
  command("bat", "densebat", BKCdensebat, false, "Creates a new [void,void] BAT 
of size 'sz'.", args(1,2, batarg("",oid),arg("sz",lng))),
  command("bat", "info", BKCinfo, false, "Produce a table containing 
information about a BAT in [attribute,value] format. \nIt contains all 
properties of the BAT record. ", args(2,3, 
batarg("",str),batarg("",str),batargany("b",1))),
  command("bat", "getSize", BKCgetSize, false, "Calculate the actual size of 
the BAT descriptor, heaps, hashes and imprint indices in bytes\nrounded to the 
memory page size (see bbp.getPageSize()).", args(1,2, 
arg("",lng),batargany("b",1))),
+ command("bat", "getVHeapSize", BKCgetVHeapSize, false, "Calculate the vheap 
size for string bats", args(1,2, arg("",lng),batargany("b",1))),
  command("bat", "getCapacity", BKCgetCapacity, false, "Returns the current 
allocation size (in max number of elements) of a BAT.", args(1,2, 
arg("",lng),batargany("b",1))),
  command("bat", "getColumnType", BKCgetColumnType, false, "Returns the type of 
the tail column of a BAT, as an integer type number.", args(1,2, 
arg("",str),batargany("b",1))),
  command("bat", "getRole", BKCgetRole, false, "Returns the rolename of the 
head column of a BAT.", args(1,2, arg("",str),batargany("bid",1))),
diff --git a/monetdb5/modules/mal/batExtensions.c 
b/monetdb5/modules/mal/batExtensions.c
--- a/monetdb5/modules/mal/batExtensions.c
+++ b/monetdb5/modules/mal/batExtensions.c
@@ -282,6 +282,21 @@ CMDBATappend_bulk(Client cntxt, MalBlkPt
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to