title: Predict size needed to store data in shared memory
body: <p>I'm working with the PHP shm (part of the <a href="http://www.php.net/manual/en/book.sem.php" rel="nofollow">semaphores extension</a>, not to be confused with the <a href="http://www.php.net/manual/en/book.shmop.php" rel="nofollow">shmop</a> ones!) functions in a project. Basically the shared memory serves as kind of heap, I have only one array inside in which I'm storing keys (with meaningless values) as hashed index, I just check "Ah, it's there already". Now my problem is: that array can get quite big at times, but it doesn't always. I don't want to reserve a huge amount of memory I don't usually need, but rather resize dynamically.</p>
  
  <p>I have registered an error handler that converts errors into <code>ErrorException</code>s, so I can <code>catch</code> the error thrown by <code>shm_put_var</code> when the memory is to small to store the array - but unfortunatly PHP clears the segment when data doesn't fit in there, so all other data is lost, too. This isn't an option therefore.</p>
  
  <p>Because of this, I need a way to predict the size I'll need to store the data. <a href="http://www.php.net/manual/en/function.shm-attach.php#85085" rel="nofollow">One of the comments to <code>shm_attach</code> at php.net</a> states that PHP appends an header of <code>(PHP_INT_SIZE * 4) + 8</code>bytes length, and one variable needs <code>strlen(serialize($foo)) + 4 * PHP_INT_SIZE) + 4</code> <em>(I have simplified the expression given in the comment, it's equal to mine but was blown up unecessarily)</em><br>
  While the header size seems to be correct (any memory smaller than 24 byte results in an error at creation, so 24 bytes seems to be the size of the header PHP puts in there), the size of each variable entry doesn't seem to hold true anymore in recent versions of PHP:<br>
   - I could store "1" in a shared memory segment with a size of <code>24 + strlen(serialize("1") + 3 * PHP_INT_SIZE) + 4</code> byte (note the <strong>3</strong> in there instead of <strong>4</strong>),<br>
   - I couldn NOT store "999" in one sized <code>24 + strlen(serialize("999") + 4 * PHP_INT_SIZE) + 4</code></p>
  
  <p>Does anyone know a way to predict how much memory is needed to store any data in shared memory using the shm functions or has some reference on how shm stores the variables? (I read the whole contets using shmop functions and printed them, but since it's binary data it's not reverse-engineerable in reasonable time)</p>
  
  <p>(I will provide code samples as needed, I'm just not sure what parts will get relevant - ping me if you want to see any working samples, I have tried much so I have samples ready for most cases)</p>
  
  <hr>
  
  <p><strong>[Update]</strong> My C is pretty bad, so I odn't get far looking at the source (<a href="http://fossies.org/dox/php-5.2.17/sysvshm_8c_source.html" rel="nofollow">sysvshm.c</a> and <a href="http://fossies.org/dox/php-5.2.17/php__sysvshm_8h_source.html" rel="nofollow">php_sysvshm.h</a>), but I already found one issue with the solution that was suggested at php.net: While I could simplify the complex formula there to what I have included here (which was taken from the C sourcecode basically), this is NOT possible with the original one, as there are typecasts and no floating point math. The formula divides by <code>sizeof(long)</code> and multiplies with it again - which is useless in PHP but does round to multiples of <code>sizeof(long)</code> on C. SO I need to correct that in PHP first. Still, this is not everything, as Tests showed that I could store some values in even less memory than returned by the formula (see above).</p>