public ulong Insert(HistogramBucket hb, ulong count) { bool found; int idx; if (bvs == null) { bvs = new HistogramBucketPair[DEFAULT_HIST_SIZE]; allocd = DEFAULT_HIST_SIZE; } found = InternalFind(hb, out idx); if (!found) { if (used == allocd) { /* A resize is required */ HistogramBucketPair[] newbvs = new HistogramBucketPair[allocd + DEFAULT_HIST_SIZE]; if (idx > 0) { Array.Copy(bvs, 0, newbvs, 0, idx); } newbvs[idx].bucket = hb; newbvs[idx].count = count; newbvs[idx].bucket = hb; newbvs[idx].count = count; if (idx < used) { Array.Copy(bvs, idx, newbvs, idx + 1, used - idx); } bvs = newbvs; allocd += DEFAULT_HIST_SIZE; } else { // used !== alloced /* We need to shuffle out data to poke the new one in */ Array.Copy(bvs, idx, bvs, idx + 1, used - idx); bvs[idx].bucket = hb; bvs[idx].count = count; } used++; } else { // found /* Just need to update the counters */ ulong newval = bvs[idx].count + count; if (newval < bvs[idx].count) /* we rolled */ { newval = ulong.MaxValue; } count = newval - bvs[idx].count; bvs[idx].count = newval; } return(count); }
private bool InternalFind(HistogramBucket hb, out int idx) { /* This is a simple binary search returning the idx in which * the specified bucket belongs... returning true if it is there * or false if the value would need to be inserted here (moving the * rest of the buckets forward one). */ int rv = -1, l = 0, r = used - 1; idx = 0; if (used == 0) { return(false); } while (l < r) { int check = (r + l) / 2; rv = bvs[check].bucket.CompareTo(hb); if (rv == 0) { l = r = check; } else if (rv > 0) { l = check + 1; } else { r = check - 1; } } /* if rv == 0 we found a match, no need to compare again */ if (rv != 0) { rv = bvs[l].bucket.CompareTo(hb); } idx = l; if (rv == 0) { return(true); /* this is it */ } if (rv < 0) { return(false); /* it goes here (before) */ } idx++; /* it goes after here */ return(false); }