Ejemplo n.º 1
0
} END_TEST

START_TEST(regions_recoveryTest) {

  Tinit();

  pageid_t pages[50];
  int xid1 = Tbegin();
  int xid2 = Tbegin();
  for(int i = 0; i < 50; i+=2) {
    pages[i] = TregionAlloc(xid1, stasis_util_random64(4)+1, 0);
    pages[i+1] = TregionAlloc(xid2, stasis_util_random64(2)+1, 0);
  }

  fsckRegions(xid1);

  Tcommit(xid1);

  Tdeinit();

  if(TdurabilityLevel() == VOLATILE) { return; }

  Tinit();

  int xid = Tbegin();
  fsckRegions(xid);

  for(int i = 0; i < 50; i+=2) {
    TregionDealloc(xid, pages[i]);
  }

  fsckRegions(xid);
  Tabort(xid);
  fsckRegions(Tbegin());
  Tdeinit();

  Tinit();
  fsckRegions(Tbegin());
  Tdeinit();

} END_TEST
Ejemplo n.º 2
0
void * worker(void * arg) {
  pageid_t *data = (pageid_t *)arg;
  for(int j = 0; j < NUM_OPS/ NUM_THREADS; j++) {
    int op = stasis_util_random64(2);

    int i = stasis_util_random64(THREAD_ENTRIES);

    pageid_t scratch = data[i];
    if(data[i] < 0) {
      scratch *= -1;
    }
    switch(op) {
    case 0: {
      void * ret;
      if(data[i] < 0) {
        ret = hashtable_insert(ht, scratch, &data[i]);
        assert(ret == NULL);
        data[i] *= -1;
      } else {
        ret = hashtable_remove(ht, scratch);
        assert(ret == &data[i]);
        data[i] *= -1;
      }
    } break;
    case 1: {
      void * ret = hashtable_lookup(ht, scratch);
      if(data[i] < 0) {
        assert(ret == NULL);
      } else {
        assert(ret == &data[i]);
      }
    } break;
    default:
      abort();
    }
  }
  free(data);
  return 0;
}
Ejemplo n.º 3
0
} END_TEST

START_TEST(wraparoundHashTest) {
  unsigned numEntries = NUM_OPS/ NUM_THREADS * 4 + 3;
  unsigned power = 1;
  while ( (1ull << power ) < numEntries ) {
    ++power;
  }
#ifdef DBUG_TEST
  ht = hashtable_init(HT_ENTRIES);
#else
  ht = hashtable_init(numEntries);
#endif
  pageid_t *data = malloc(sizeof(pageid_t) * THREAD_ENTRIES);

  for(int i = 1; i <= THREAD_ENTRIES; i++) {
    data[i-1] = -1 * (((i << power) - 6 + stasis_util_random64(13)) / 13);
  }
  worker(data);
  hashtable_deinit(ht);
} END_TEST
Ejemplo n.º 4
0
} END_TEST

START_TEST(regions_lockRandomizedTest) {
  Tinit();

  const int NUM_XACTS = 100;
  const int NUM_OPS   = 10000;
  const int FUDGE = 10;
  int xids[NUM_XACTS];

  pageid_t * xidRegions[NUM_XACTS + FUDGE];
  int xidRegionCounts[NUM_XACTS + FUDGE];

  int longXid = Tbegin();

  time_t seed = time(0);
  printf("\nSeed = %ld\n", seed);
  srandom(seed);

  for(int i = 0; i < NUM_XACTS; i++) {
    xids[i] = Tbegin();
    assert(xids[i] < NUM_XACTS + FUDGE);
    xidRegions[xids[i]] = stasis_malloc(NUM_OPS, pageid_t);
    xidRegionCounts[xids[i]] = 0;
  }
  int activeXacts = NUM_XACTS;

  for(int i = 0; i < NUM_OPS; i++) {
    pageid_t j;
    if(!(i % (NUM_OPS/NUM_XACTS))) {
      // abort or commit one transaction randomly.
      activeXacts --;
      j = stasis_util_random64(activeXacts);

      if(stasis_util_random64(2)) {
	Tcommit(xids[j]);
      } else {
	Tabort(xids[j]);
      }

      if(activeXacts == 0) {
	break;
      }
      for(; j < activeXacts; j++) {
	xids[j] = xids[j+1];
      }
      fsckRegions(longXid);
    }

    j = stasis_util_random64(activeXacts);

    if(stasis_util_random64(2)) {
      // alloc
      xidRegions[xids[j]][xidRegionCounts[xids[j]]] = TregionAlloc(xids[j], stasis_util_random64(100), 0);
	xidRegionCounts[xids[j]]++;
    } else {
      // free
      if(xidRegionCounts[xids[j]]) {
	pageid_t k = stasis_util_random64(xidRegionCounts[xids[j]]);

	TregionDealloc(xids[j], xidRegions[xids[j]][k]);

	xidRegionCounts[xids[j]]--;

	for(; k < xidRegionCounts[xids[j]]; k++) {
	  xidRegions[xids[j]][k] = xidRegions[xids[j]][k+1];
	}
      }
    }
  }

  for(int i = 0; i < activeXacts; i++) {
    Tabort(i);
    fsckRegions(longXid);
  }

  Tcommit(longXid);

  Tdeinit();
} END_TEST
Ejemplo n.º 5
0
END_TEST

START_TEST(regions_randomizedTest) {
  Tinit();
  time_t seed = time(0);
  printf("Seed = %ld: ", seed);
  srandom(seed);
  int xid = Tbegin();
  pageid_t pagesAlloced = 0;
  pageid_t regionsAlloced = 0;
  double max_blowup = 0;
  pageid_t max_region_count = 0;
  pageid_t max_waste = 0;
  pageid_t max_size = 0;
  pageid_t max_ideal_size = 0;
  for(int i = 0; i < 10000; i++) {
    if(!(i % 100)) {
      Tcommit(xid);
      xid = Tbegin();
    }
    if(!(i % 100)) {
      fsckRegions(xid);
    }

    if(stasis_util_random64(2)) {
      unsigned int size = stasis_util_random64(100);
      TregionAlloc(xid, size, 0);
      pagesAlloced += size;
      regionsAlloced ++;
    } else {
      if(regionsAlloced) {
	pageid_t victim = stasis_util_random64(regionsAlloced);
	pageid_t victimSize;
	pageid_t victimPage;
	TregionFindNthActive(xid, victim, &victimPage, &victimSize);
	TregionDealloc(xid, victimPage);
	pagesAlloced -= victimSize;
	regionsAlloced --;
      } else {
	i--;
      }
    }

    if(regionsAlloced) {
      pageid_t lastRegionStart;
      pageid_t lastRegionSize;

      TregionFindNthActive(xid, regionsAlloced-1, &lastRegionStart, &lastRegionSize);
      pageid_t length = lastRegionStart + lastRegionSize+1;
      pageid_t ideal  = pagesAlloced + regionsAlloced + 1;
      double blowup = (double)length/(double)ideal;
      unsigned long long bytes_wasted = length - ideal;
      // printf("Region count = %d, blowup = %d / %d = %5.2f\n", regionsAlloced, length, ideal, blowup);
      if(max_blowup < blowup) {
	max_blowup = blowup;
      }
      if(max_waste < bytes_wasted) {
	max_waste = bytes_wasted;
      }
      if(max_size < length) {
	max_size = length;
      }
      if(max_ideal_size < ideal) {
	max_ideal_size = ideal;
      }
      if(max_region_count < regionsAlloced) {
	max_region_count = regionsAlloced;
      }
    }
  }
  fsckRegions(xid);
  Tcommit(xid);

  Tdeinit();
  printf("Max # of regions = %lld, page file size = %5.2fM, ideal page file size = %5.2fM, (blowup = %5.2f)\n",
	 //peak bytes wasted = %5.2fM, blowup = %3.2f\n",
	 max_region_count,
	 ((double)max_size * PAGE_SIZE)/(1024.0*1024.0),
	 ((double)max_ideal_size * PAGE_SIZE)/(1024.0*1024.0),
	 (double)max_size/(double)max_ideal_size);
  //	 ((double)max_waste * PAGE_SIZE)/(1024.0*1024.0),
  //	 max_blowup);
  if((double)max_size/(double)max_ideal_size > 5) {
    // max_blowup isn't what we want here; it measures the peak
    // percentage of the file that is unused.  Instead, we want to
    // measure the actual and ideal page file sizes for this run.
    printf("ERROR: Excessive blowup (max allowable is 5)\n");
    abort();
  }

} END_TEST