Branch: Tag:

2013-12-10

2013-12-10 11:22:02 by Henrik Grubbström (Grubba) <grubba@grubba.org>

ImageCache: Allow for larger images.

Changes the data field from a mediumblob (max 16MB) to a largeblob (max 4GB).

Updates large fields in chunks of 8MB.

Fixes some of [bug 6938 (#6938)].

4006: Inside #if defined(ARG_CACHE_DEBUG)
  #ifdef ARG_CACHE_DEBUG    werror("Replacing entry for %O\n", id );   #endif -  QUERY("REPLACE INTO "+name+ +  if (sizeof(data) <= 8*1024*1024) { +  // Should fit in the 16 MB query limit without problem. +  // Albeit it might trigger a slow query entry for large +  // entries. +  QUERY("REPLACE INTO " + name +    " (id,size,atime,meta,data) VALUES"    " (%s,%d,UNIX_TIMESTAMP()," MYSQL__BINARY "%s," MYSQL__BINARY "%s)",    id, strlen(data)+strlen(meta_data), meta_data, data ); -  +  } else { +  // We need to perform multiple queries.   #ifdef ARG_CACHE_DEBUG -  +  werror("Writing %d bytes of padding for %s.\n", sizeof(data), id); + #endif +  array(string) a = data/(8.0*1024*1024); +  // NB: We clear the meta field to ensure that the entry +  // is invalid while we perform the insert. +  QUERY("REPLACE INTO " + name + +  " (id,size,atime,meta,data) VALUES" +  " (%s,%d,UNIX_TIMESTAMP(),'',SPACE(%d))", +  id, strlen(data)+strlen(meta_data), sizeof(data)); +  int pos; +  foreach(a, string frag) { + #ifdef ARG_CACHE_DEBUG +  werror("Writing fragment at position %d for %s.\n", pos, id); + #endif +  QUERY("UPDATE " + name + +  " SET data = INSERT(data, %d, %d, "MYSQL__BINARY "%s)" +  " WHERE id = %s", +  pos+1, sizeof(frag), frag, id); +  pos += sizeof(frag); +  } +  /* Set the meta data field to a valid value to enable the entry. */ + #ifdef ARG_CACHE_DEBUG +  werror("Writing metadata for %s.\n", id); + #endif +  QUERY("UPDATE " + name + +  " SET meta = " MYSQL__BINARY "%s" +  " WHERE id = %s", +  meta_data, id); +  } + #ifdef ARG_CACHE_DEBUG    array(mapping(string:string)) q =    QUERY("SELECT meta, data FROM " + name +    " WHERE id = %s", id);
4023: Inside #if defined(ARG_CACHE_DEBUG)
   meta_data, q[0]->meta);    }    if (q[0]->data != data) { -  werror("Data differs: %O != %O\n", -  data, q[0]->data); +  string d = q[0]->data; +  int i; +  int cnt; +  for (i = 0; i < sizeof(data); i++) { +  if (data[i] == d[i]) continue; +  werror("Data differs at offset %d: %d != %d\n", +  i, data[i], d[i]); +  if (cnt++ > 10) break;    }    } -  +  }   #endif    }   
4458:    "uid CHAR(32) NOT NULL DEFAULT '', "    "atime INT UNSIGNED NOT NULL DEFAULT 0,"    "meta MEDIUMBLOB NOT NULL DEFAULT ''," -  "data MEDIUMBLOB NOT NULL DEFAULT ''," +  "data LARGEBLOB NOT NULL DEFAULT '',"    "INDEX atime_id (atime, id)"    ")" );    }
4479:    QUERY("DROP INDEX atime ON " + name);    report_debug("complete. [%f s]\n", (gethrtime() - start_time)/1000000.0);    } +  res = QUERY("SHOW COLUMNS FROM " + name + " WHERE Field = 'data'"); +  if (lowercase(res[0]->Type) != "longblob") { +  report_debug("Updating " + name + " image cache: " +  "Increasing maximum blob size..."); +  start_time = gethrtime(); +  QUERY("ALTER TABLE " + name + +  "MODIFY COLUMN data LONGBLOB NOT NULL DEFAULT ''"); +  report_debug("complete. [%f s]\n", (gethrtime() - start_time)/1000000.0);    } -  +  }       Sql.Sql get_db()    {