chiark / gitweb /
WIP routetrade now can find trades for islandpair but FIXME need to get max islandid
[ypp-sc-tools.db-live.git] / yarrg / rsvalue.c
index f399e3f51abcc00d1538d9173193ccc84712011b..b17693561552f879bed56cb76704dffe96f1fa60 100644 (file)
@@ -2,36 +2,67 @@
 
 #include "rscommon.h"
 
-DEBUG_DEFINE_SOME_DEBUGF(sql,sql_dprintf);
+//DEBUG_DEFINE_SOME_DEBUGF(sql,sql_dprintf);
 
 typedef struct {
   int commodid, src_price, src_qty, dst_price, dst_qty;
 } Trade;
 
+#define TRADES_PER_BLOCK 10
+
+typedef struct TradesBlock{
+  struct TradesBlock *next;
+  Trade t[TRADES_PER_BLOCK];
+} TradesBlock;
+
 typedef struct {
   int ntrades;
-  Trade *trades;
+  TradesBlock *trades;
 } IslandPair;
 
-static void ipair_gettrades(int si, int di) {
-  char *stmt= masprintf
-    ("SELECT\n"
-     " sell.commodid           commodid,\n"
-     " sell.price              src_price,\n"
-     " sum(sell.qty)           src_qty,\n"
-     " buy.price               dst_price,\n"
-     " sum(buy.qty)            dst_qty\n"
-     " FROM sell JOIN buy\n"
-     "   ON sell.commodid = buy.commodid\n"
-     "  AND buy.price > sell.price\n"
-     " WHERE sell.islandid=%d\n"
-     "  AND buy.islandid=%d\n"
-     " GROUP BY sell.commodid, sell.price, buy.price\n",
-     si, di);
+int nislands=100;
+IslandPair ***ipairs; /* ipairs[sislandid][dislandid] */
+
+static IslandPair *ipair_get(int si, int di) {
+  IslandPair *ip, **ipa;
+
+  assert(si < nislands);
+  assert(di < nislands);
+
+  if (!(ipa= ipairs[si])) {
+    ipa= ipairs[si]= mcalloc(sizeof(*ipa) * nislands);
+  }
+  if ((ip= ipa[di]))
+    return ip;
   
-  sql_dprintf("SQL\n[\n%s\n]\n", stmt);
+  ipa[di]= ip= mmalloc(sizeof(*ip));
+  ip->ntrades= 0;
+  ip->trades= 0;
+  int inblock= TRADES_PER_BLOCK;
+  TradesBlock *block= 0;
+
+  SQL_MUST( sqlite3_bind_int(ss_ipair, 1, si) );
+  SQL_MUST( sqlite3_bind_int(ss_ipair, 2, di) );
 
-  free(stmt);
+  while (SQL_STEP(ss_ipair)) {
+    if (inblock == TRADES_PER_BLOCK) {
+      block= mmalloc(sizeof(*block));
+      block->next= ip->trades;
+      ip->trades= block;
+      inblock= 0;
+    }
+    int *irp, i;
+    for (i=0, irp=&block->t[inblock].commodid; i<5; i++, irp++)
+      *irp= sqlite3_column_int(ss_ipair, i);
+    ip->ntrades++;
+    inblock++;
+  }
+  if (inblock < TRADES_PER_BLOCK)
+    block->t[inblock].commodid= -1;
+
+  sqlite3_reset(ss_ipair);
+  
+  return ip;
 }
 
 void value_route(int nislands, const int *islands) {
@@ -39,7 +70,7 @@ void value_route(int nislands, const int *islands) {
   
   for (s=0; s<nislands; s++) {
     for (d=s; d<nislands; d++) {
-      ipair_gettrades(islands[s], islands[d]);
+      ipair_get(islands[s], islands[d]);
     }
   }
 
@@ -47,3 +78,22 @@ void value_route(int nislands, const int *islands) {
   //struct sqlite_vm *sth;
   //r= sqlite_compile(db, stmt, &tail, &sth, 
 }
+
+void setup_value(void) {
+  SQL_MUST( sqlite3_prepare(db,
+     "SELECT\n"
+     " sell.commodid           commodid,\n"
+     " sell.price              src_price,\n"
+     " sum(sell.qty)           src_qty,\n"
+     " buy.price               dst_price,\n"
+     " sum(buy.qty)            dst_qty\n"
+     " FROM sell JOIN buy\n"
+     "   ON sell.commodid = buy.commodid\n"
+     "  AND buy.price > sell.price\n"
+     " WHERE sell.islandid=?\n"
+     "   AND buy.islandid=?\n"
+     " GROUP BY sell.commodid, sell.price, buy.price",
+                           -1, &ss_ipair, 0) );
+
+  ipairs= mcalloc(sizeof(*ipairs) * nislands);
+}