Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
tests_mem2_adjustStats.c208 linesDownload Raw Back to tests
1#include "sqliteInt.h"2#include "unity.h"3 4#include <stdio.h>5#include <stdlib.h>6#include <string.h>7 8/* External functions from mem2.c (globally visible due to build flags) */9extern void test_adjustStats(int iSize, int increment);10extern void sqlite3MemdebugDump(const char *zFilename);11extern int sqlite3MemdebugMallocCount(void);12 13/* Local constant mirroring mem2.c */14#define NCSIZE_TEST 100015 16static int dumpCounter = 0;17 18/* Helper: compute bucket index from size using ROUND8 and clamping */19static int bucket_index_from_size(int iSize){20  int i = ROUND8(iSize)/8;21  if( i > NCSIZE_TEST-1 ) i = NCSIZE_TEST-1;22  if( i < 0 ) i = 0;23  return i;24}25 26/* Helper: parse the COUNTS section from a memdebug dump file */27static void parse_counts_file(const char *path, int *alloc, int *current, int *mx){28  FILE *f = fopen(path, "r");29  TEST_ASSERT_MESSAGE(f != NULL, "Failed to open memdebug dump file");30 31  char line[512];32  int inCounts = 0;33  /* Initialize arrays to zero */34  for( int i = 0; i < NCSIZE_TEST; i++ ){35    alloc[i] = 0;36    current[i] = 0;37    mx[i] = 0;38  }39 40  while( fgets(line, sizeof(line), f) ){41    if( !inCounts ){42      if( strncmp(line, "COUNTS:", 7) == 0 ){43        inCounts = 1;44      }45    }else{46      int bytes = 0, a = 0, c = 0, m = 0;47      /* Lines look like: "   %5d: %10d %10d %10d\n" */48      if( sscanf(line, " %d: %d %d %d", &bytes, &a, &c, &m) == 4 ){49        int idx = bytes / 8;50        if( idx >= 0 && idx < NCSIZE_TEST ){51          alloc[idx]   = a;52          current[idx] = c;53          mx[idx]      = m;54        }55      }56    }57  }58  fclose(f);59}60 61/* Helper: dump current memory debug state and parse out counters */62static void snapshot_counts(int *alloc, int *current, int *mx){63  char fname[128];64  snprintf(fname, sizeof(fname), "mem2_counts_snapshot_%d.txt", ++dumpCounter);65  sqlite3MemdebugDump(fname);66  parse_counts_file(fname, alloc, current, mx);67  remove(fname);68}69 70void setUp(void) {71  /* No special setup required */72}73 74void tearDown(void) {75  /* No special teardown required */76}77 78/* Test that increments go to the correct rounded bucket and update counts */79void test_adjustStats_increments_and_rounding(void){80  int beforeAlloc[NCSIZE_TEST], beforeCur[NCSIZE_TEST], beforeMx[NCSIZE_TEST];81  int afterAlloc[NCSIZE_TEST],  afterCur[NCSIZE_TEST],  afterMx[NCSIZE_TEST];82 83  /* Snapshot before */84  int totalBefore = sqlite3MemdebugMallocCount();85  snapshot_counts(beforeAlloc, beforeCur, beforeMx);86 87  /* Sizes chosen to exercise rounding and multiple buckets */88  int sizes[] = { 0, 1, 7, 8, 9, 15, 16, 24, 25, 1003 };89  int nSizes = (int)(sizeof(sizes)/sizeof(sizes[0]));90 91  /* Track expected increments per bucket */92  int incPerBucket[NCSIZE_TEST];93  memset(incPerBucket, 0, sizeof(incPerBucket));94 95  for( int i = 0; i < nSizes; i++ ){96    int idx = bucket_index_from_size(sizes[i]);97    incPerBucket[idx]++;98    test_adjustStats(sizes[i], +1);99  }100 101  /* Snapshot after */102  int totalAfter = sqlite3MemdebugMallocCount();103  snapshot_counts(afterAlloc, afterCur, afterMx);104 105  /* Verify total allocation count delta */106  TEST_ASSERT_EQUAL_INT_MESSAGE(nSizes, totalAfter - totalBefore,107                                "Total alloc count delta mismatch");108 109  /* Verify per-bucket deltas and mx invariants */110  for( int i = 0; i < NCSIZE_TEST; i++ ){111    if( incPerBucket[i] > 0 ){112      TEST_ASSERT_EQUAL_INT_MESSAGE(beforeAlloc[i] + incPerBucket[i], afterAlloc[i],113                                    "nAlloc per-bucket increment mismatch");114      TEST_ASSERT_EQUAL_INT_MESSAGE(beforeCur[i] + incPerBucket[i], afterCur[i],115                                    "nCurrent per-bucket increment mismatch");116      TEST_ASSERT_TRUE_MESSAGE(afterMx[i] >= beforeMx[i],117                               "mxCurrent should not decrease");118      TEST_ASSERT_TRUE_MESSAGE(afterMx[i] >= afterCur[i],119                               "mxCurrent should be >= current");120    }121  }122}123 124/* Test that decrements reduce current without affecting alloc and that mx reaches the high-water mark */125void test_adjustStats_decrement_balances_current_and_mx(void){126  int beforeAlloc[NCSIZE_TEST], beforeCur[NCSIZE_TEST], beforeMx[NCSIZE_TEST];127  int afterAlloc[NCSIZE_TEST],  afterCur[NCSIZE_TEST],  afterMx[NCSIZE_TEST];128 129  /* Choose a size and repeat count for a single bucket */130  int size = 12345; /* arbitrary mid-range size */131  int idx = bucket_index_from_size(size);132  int k = 5;133 134  int totalBefore = sqlite3MemdebugMallocCount();135  snapshot_counts(beforeAlloc, beforeCur, beforeMx);136 137  for( int i = 0; i < k; i++ ){138    test_adjustStats(size, +1);139  }140  for( int i = 0; i < k; i++ ){141    test_adjustStats(size, -1);142  }143 144  int totalAfter = sqlite3MemdebugMallocCount();145  snapshot_counts(afterAlloc, afterCur, afterMx);146 147  /* nAlloc increases by k (decrements do not affect nAlloc) */148  TEST_ASSERT_EQUAL_INT_MESSAGE(beforeAlloc[idx] + k, afterAlloc[idx],149                                "nAlloc should increase only by number of increments");150 151  /* nCurrent returns to its original value after k increments then k decrements */152  TEST_ASSERT_EQUAL_INT_MESSAGE(beforeCur[idx], afterCur[idx],153                                "nCurrent should return to original after balanced decs");154 155  /* mxCurrent should be at least max(beforeMx, beforeCur + k) */156  {157    int expectedMinMx = beforeCur[idx] + k;158    if( expectedMinMx < beforeMx[idx] ) expectedMinMx = beforeMx[idx];159    TEST_ASSERT_TRUE_MESSAGE(afterMx[idx] >= expectedMinMx,160                             "mxCurrent did not reach expected high-water mark");161  }162 163  /* Total malloc count reflects only increments */164  TEST_ASSERT_EQUAL_INT_MESSAGE(k, totalAfter - totalBefore,165                                "Total alloc count delta mismatch for inc/dec test");166}167 168/* Test that very large sizes clamp to the last bucket (index NCSIZE-1) */169void test_adjustStats_clamps_to_last_bucket(void){170  int beforeAlloc[NCSIZE_TEST], beforeCur[NCSIZE_TEST], beforeMx[NCSIZE_TEST];171  int afterAlloc[NCSIZE_TEST],  afterCur[NCSIZE_TEST],  afterMx[NCSIZE_TEST];172 173  const int lastIdx = NCSIZE_TEST - 1;174  /* Choose a size well beyond the last bucket to force clamping */175  int hugeSize = 8 * (NCSIZE_TEST + 500); /* clearly beyond */176 177  TEST_ASSERT_EQUAL_INT(lastIdx, bucket_index_from_size(hugeSize));178 179  int totalBefore = sqlite3MemdebugMallocCount();180  snapshot_counts(beforeAlloc, beforeCur, beforeMx);181 182  int reps = 3;183  for( int i = 0; i < reps; i++ ){184    test_adjustStats(hugeSize, +1);185  }186 187  int totalAfter = sqlite3MemdebugMallocCount();188  snapshot_counts(afterAlloc, afterCur, afterMx);189 190  TEST_ASSERT_EQUAL_INT_MESSAGE(beforeAlloc[lastIdx] + reps, afterAlloc[lastIdx],191                                "Last bucket nAlloc mismatch");192  TEST_ASSERT_EQUAL_INT_MESSAGE(beforeCur[lastIdx] + reps, afterCur[lastIdx],193                                "Last bucket nCurrent mismatch");194  TEST_ASSERT_TRUE_MESSAGE(afterMx[lastIdx] >= beforeMx[lastIdx],195                           "Last bucket mxCurrent should not decrease");196  TEST_ASSERT_TRUE_MESSAGE(afterMx[lastIdx] >= afterCur[lastIdx],197                           "Last bucket mxCurrent should be >= current");198  TEST_ASSERT_EQUAL_INT_MESSAGE(reps, totalAfter - totalBefore,199                                "Total alloc count delta mismatch for clamp test");200}201 202int main(void){203  UNITY_BEGIN();204  RUN_TEST(test_adjustStats_increments_and_rounding);205  RUN_TEST(test_adjustStats_decrement_balances_current_and_mx);206  RUN_TEST(test_adjustStats_clamps_to_last_bucket);207  return UNITY_END();208}