#ident "Copyright (c) 2007-2012 Tokutek Inc. All rights reserved."
#ident "The technology is licensed by the Massachusetts Institute of Technology, Rutgers State University of New Jersey, and the Research Foundation of State University of New York at Stony Brook under United States of America Serial No. 11/760379 and to the patents and/or patent applications resulting from it."
// Overview: A partitioned_counter provides a counter that can be incremented and the running sum can be read at any time.
// We assume that increments are frequent, whereas reading is infrequent.
// Implementation hint: Use thread-local storage so each thread increments its own data. The increment does not require a lock or atomic operation.
// Reading the data can be performed by iterating over the thread-local versions, summing them up.
// The data structure also includes a sum for all the threads that have died.
// Use a pthread_key to create the thread-local versions. When a thread finishes, the system calls pthread_key destructor which can add that thread's copy
// into the sum_of_dead counter.
// Rationale: For statistics such as are found in engine status, we need a counter that requires no cache misses to increment. We've seen significant
// performance speedups by removing certain counters. Rather than removing those statistics, we would like to just make the counter fast.
// We generally increment the counters frequently, and want to fetch the values infrequently.
// The counters are monotonic.
// The counters can be split into many counters, which can be summed up at the end.
// We don't care if we get slightly out-of-date counter sums when we read the counter. We don't care if there is a race on reading the a counter
// variable and incrementing.
// See tests/test_partitioned_counter.c for some performance measurements.
// Operations:
// create_partitioned_counter Create a counter initialized to zero.
// destroy_partitioned_counter Destroy it.
// increment_partitioned_counter Increment it. This is the frequent operation.
// read_partitioned_counter Get the current value. This is infrequent.
// Effect: Initialize any partitioned counters data structures that must be set up before any partitioned counters run.
voidpartitioned_counters_destroy(void);
// Effect: Destroy any partitioned counters data structures.
#if 0
#include<pthread.h>
#include"fttypes.h"
// Used inside the PARTITIONED_COUNTER.
structlinked_list_head{
structlinked_list_element*first;
};
classPARTITIONED_COUNTER{
public:
PARTITIONED_COUNTER(void);
// Effect: Construct a counter, initialized to zero.
~PARTITIONED_COUNTER(void);
// Effect: Destruct the counter.
voidincrement(uint64_tamount);
// Effect: Increment the counter by amount. This is a 64-bit unsigned counter, and if you overflow it, you will get overflowed results (that is mod 2^64).
// Requires: Don't use this from a static constructor or destructor.
uint64_tread(void);
// Effect: Read the sum.
// Requires: Don't use this from a static constructor or destructor.
private:
uint64_t_sum_of_dead;// The sum of all thread-local counts from threads that have terminated.
pthread_key_t_key;// The pthread_key which gives us the hook to construct and destruct thread-local storage.
structlinked_list_head_ll_counter_head;// A linked list of all the thread-local information for this counter.
// This function is used to destroy the thread-local part of the state when a thread terminates.
// But it's not the destructor for the local part of the counter, it's a destructor on a "dummy" key just so that we get a notification when a thread ends.