This is an automated email from the ASF dual-hosted git repository.
bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new db0c1f9 Cleanup: Remove Map.h including HashMap, Vec and TSHashTable
db0c1f9 is described below
commit db0c1f9d3ddd8fb120a4dd9534039c45bd9156ed
Author: Xavier Chi <[email protected]>
AuthorDate: Mon Nov 26 13:51:12 2018 -0600
Cleanup: Remove Map.h including HashMap, Vec and TSHashTable
---
include/tscore/Map.h | 2228 -------------------------------------
iocore/net/P_SNIActionPerformer.h | 4 +-
iocore/net/P_SSLConfig.h | 2 +-
iocore/net/P_SSLNetProcessor.h | 1 -
iocore/net/P_SSLSNI.h | 4 +-
iocore/net/SNIActionPerformer.cc | 2 +-
iocore/net/SSLConfig.cc | 2 +-
iocore/net/SSLNetVConnection.cc | 2 +-
iocore/net/SSLSNIConfig.cc | 12 +-
iocore/net/SSLSessionCache.h | 1 -
src/tscore/Makefile.am | 5 +-
src/tscore/suppression.txt | 1 -
src/tscore/unit_tests/test_Map.cc | 215 ----
src/tscore/unit_tests/test_Vec.cc | 388 -------
14 files changed, 15 insertions(+), 2852 deletions(-)
diff --git a/include/tscore/Map.h b/include/tscore/Map.h
deleted file mode 100644
index 5114bbf..0000000
--- a/include/tscore/Map.h
+++ /dev/null
@@ -1,2228 +0,0 @@
-/** @file
-
- A set of Map templates.
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-#pragma once
-
-#include <cstdlib>
-#include <cstring>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include "tscore/defalloc.h"
-#include "tscore/ink_assert.h"
-#include "tscore/Diags.h"
-
-#include "tscore/List.h"
-
-#define MAP_INTEGRAL_SIZE (1 << (2))
-//#define MAP_INITIAL_SHIFT ((2)+1)
-//#define MAP_INITIAL_SIZE (1 << MAP_INITIAL_SHIFT)
-
-// Simple Vector class, also supports open hashed sets
-#define VEC_INTEGRAL_SHIFT_DEFAULT 2 /* power of 2 (1 << VEC_INTEGRAL_SHIFT)*/
-#define VEC_INTEGRAL_SIZE (1 << (S))
-#define VEC_INITIAL_SHIFT ((S) + 1)
-#define VEC_INITIAL_SIZE (1 << VEC_INITIAL_SHIFT)
-
-#define SET_LINEAR_SIZE 4 /* must be <= than VEC_INTEGRAL_SIZE */
-#define SET_INITIAL_INDEX 2
-
-template <class C, class A = DefaultAlloc, int S = VEC_INTEGRAL_SHIFT_DEFAULT>
// S must be a power of 2
-class Vec
-{
-public:
- size_t n;
- size_t i; // size index for sets, reserve for vectors
- C *v;
- C e[VEC_INTEGRAL_SIZE];
-
- Vec();
- Vec<C, A, S>(const Vec<C, A, S> &vv);
- Vec<C, A, S>(const C c);
- ~Vec();
-
- C &operator[](int i) const { return v[i]; }
- C get(size_t i) const;
- void add(C a);
- void
- push_back(C a)
- {
- add(a);
- } // std::vector name
- bool add_exclusive(C a);
- C &add();
- void drop();
- C pop();
- void reset();
- void clear();
- void free_and_clear();
- void delete_and_clear();
- void set_clear();
- C *set_add(C a);
- void set_remove(C a); // expensive, use BlockHash for cheaper remove
- C *set_add_internal(C a);
- bool set_union(Vec<C, A, S> &v);
- int set_intersection(Vec<C, A, S> &v);
- int some_intersection(Vec<C, A, S> &v);
- int some_disjunction(Vec<C, A, S> &v);
- int some_difference(Vec<C, A, S> &v);
- void set_intersection(Vec<C, A, S> &v, Vec<C, A, S> &result);
- void set_disjunction(Vec<C, A, S> &v, Vec<C, A, S> &result);
- void set_difference(Vec<C, A, S> &v, Vec<C, A, S> &result);
- size_t set_count() const;
- size_t count() const;
- C *in(C a);
- C *set_in(C a);
- C first_in_set();
- C *set_in_internal(C a);
- void set_expand();
- ssize_t index(C a) const;
- void set_to_vec();
- void vec_to_set();
- void move(Vec<C, A, S> &v);
- void copy(const Vec<C, A, S> &v);
- void fill(size_t n);
- void append(const Vec<C> &v);
- template <typename CountType> void append(const C *src, CountType count);
- void prepend(const Vec<C> &v);
- void remove_index(int index);
- void
- remove(C a)
- {
- int i = index(a);
- if (i >= 0)
- remove_index(i);
- }
- C &insert(size_t index);
- void insert(size_t index, Vec<C> &vv);
- void insert(size_t index, C a);
- void
- push(C a)
- {
- insert(0, a);
- }
- void reverse();
- void reserve(size_t n);
- C *
- end() const
- {
- return v + n;
- }
- C &
- first() const
- {
- return v[0];
- }
- C &
- last() const
- {
- return v[n - 1];
- }
- Vec<C, A, S> &
- operator=(Vec<C, A, S> &v)
- {
- this->copy(v);
- return *this;
- }
- unsigned
- length() const
- {
- return n;
- }
- // vector::size() intentionally not implemented because it should mean
"bytes" not count of elements
- int write(int fd);
- int read(int fd);
- void qsort(bool (*lt)(C, C));
- void qsort(bool (*lt)(const C &, const C &));
- static void swap(C *p1, C *p2);
-
-private:
- void move_internal(Vec<C, A, S> &v);
- void copy_internal(const Vec<C, A, S> &v);
- void add_internal(C a);
- C &add_internal();
- void addx();
-};
-
-// c -- class, p -- pointer to elements of v, v -- vector
-#define forv_Vec(_c, _p, _v)
\
- if ((_v).n)
\
- for (_c *qq__##_p = (_c *)0, *_p = (_v).v[0];
\
- ((uintptr_t)(qq__##_p) < (_v).length()) && ((_p =
(_v).v[(intptr_t)qq__##_p]), 1); \
- qq__##_p = (_c *)(((intptr_t)qq__##_p) + 1))
-#define for_Vec(_c, _p, _v)
\
- if ((_v).n)
\
- for (_c *qq__##_p = (_c *)0, _p = (_v).v[0];
\
- ((uintptr_t)(qq__##_p) < (_v).length()) && ((_p =
(_v).v[(intptr_t)qq__##_p]), 1); \
- qq__##_p = (_c *)(((intptr_t)qq__##_p) + 1))
-#define forvp_Vec(_c, _p, _v)
\
- if ((_v).n)
\
- for (_c *qq__##_p = (_c *)0, *_p = &(_v).v[0];
\
- ((uintptr_t)(qq__##_p) < (_v).length()) && ((_p =
&(_v).v[(intptr_t)qq__##_p]), 1); \
- qq__##_p = (_c *)(((intptr_t)qq__##_p) + 1))
-
-template <class C, class A = DefaultAlloc, int S = VEC_INTEGRAL_SHIFT_DEFAULT>
class Accum
-{
-public:
- Vec<C, A, S> asset;
- Vec<C, A, S> asvec;
- void
- add(C c)
- {
- if (asset.set_add(c))
- asvec.add(c);
- }
- void
- add(Vec<C, A, S> v)
- {
- for (int i = 0; i < v.n; i++)
- if (v.v[i])
- add(v.v[i]);
- }
- void
- clear()
- {
- asset.clear();
- asvec.clear();
- }
-};
-
-const uintptr_t prime2[] = {1, 3, 7, 13, 31, 61,
127, 251, 509, 1021,
- 2039, 4093, 8191, 16381, 32749,
65521, 131071, 262139, 524287, 1048573,
- 2097143, 4194301, 8388593, 16777213, 33554393,
67108859, 134217689, 268435399, 536870909};
-
-// primes generated with map_mult.c
-const uintptr_t open_hash_primes[256] = {
- 0x02D4AF27, 0x1865DFC7, 0x47C62B43, 0x35B4889B, 0x210459A1, 0x3CC51CC7,
0x02ADD945, 0x0607C4D7, 0x558E6035, 0x0554224F,
- 0x5A281657, 0x1C458C7F, 0x7F8BE723, 0x20B9BA99, 0x7218AA35, 0x64B10C2B,
0x548E8983, 0x5951218F, 0x7AADC871, 0x695FA5B1,
- 0x40D40FCB, 0x20E03CC9, 0x55E9920F, 0x554CE08B, 0x7E78B1D7, 0x7D965DF9,
0x36A520A1, 0x1B0C6C11, 0x33385667, 0x2B0A7B9B,
- 0x0F35AE23, 0x0BD608FB, 0x2284ADA3, 0x6E6C0687, 0x129B3EED, 0x7E86289D,
0x1143C24B, 0x1B6C7711, 0x1D87BB41, 0x4C7E635D,
- 0x67577999, 0x0A0113C5, 0x6CF085B5, 0x14A4D0FB, 0x4E93E3A7, 0x5C87672B,
0x67F3CA17, 0x5F944339, 0x4C16DFD7, 0x5310C0E3,
- 0x2FAD1447, 0x4AFB3187, 0x08468B7F, 0x49E56C51, 0x6280012F, 0x097D1A85,
0x34CC9403, 0x71028BD7, 0x6DEDC7E9, 0x64093291,
- 0x6D78BB0B, 0x7A03B465, 0x2E044A43, 0x1AE58515, 0x23E495CD, 0x46102A83,
0x51B78A59, 0x051D8181, 0x5352CAC9, 0x57D1312B,
- 0x2726ED57, 0x2E6BC515, 0x70736281, 0x5938B619, 0x0D4B6ACB, 0x44AB5E2B,
0x0029A485, 0x002CE54F, 0x075B0591, 0x3EACFDA9,
- 0x0AC03411, 0x53B00F73, 0x2066992D, 0x76E72223, 0x55F62A8D, 0x3FF92EE1,
0x17EE0EB3, 0x5E470AF1, 0x7193EB7F, 0x37A2CCD3,
- 0x7B44F7AF, 0x0FED8B3F, 0x4CC05805, 0x7352BF79, 0x3B61F755, 0x523CF9A3,
0x1AAFD219, 0x76035415, 0x5BE84287, 0x6D598909,
- 0x456537E9, 0x407EA83F, 0x23F6FFD5, 0x60256F39, 0x5D8EE59F, 0x35265CEB,
0x1D4AD4EF, 0x676E2E0F, 0x2D47932D, 0x776BB33B,
- 0x6DE1902B, 0x2C3F8741, 0x5B2DE8EF, 0x686DDB3B, 0x1D7C61C7, 0x1B061633,
0x3229EA51, 0x7FCB0E63, 0x5F22F4C9, 0x517A7199,
- 0x2A8D7973, 0x10DCD257, 0x41D59B27, 0x2C61CA67, 0x2020174F, 0x71653B01,
0x2FE464DD, 0x3E7ED6C7, 0x164D2A71, 0x5D4F3141,
- 0x5F7BABA7, 0x50E1C011, 0x140F5D77, 0x34E80809, 0x04AAC6B3, 0x29C42BAB,
0x08F9B6F7, 0x461E62FD, 0x45C2660B, 0x08BF25A7,
- 0x5494EA7B, 0x0225EBB7, 0x3C5A47CF, 0x2701C333, 0x457ED05B, 0x48CDDE55,
0x14083099, 0x7C69BDAB, 0x7BF163C9, 0x41EE1DAB,
- 0x258B1307, 0x0FFAD43B, 0x6601D767, 0x214DBEC7, 0x2852CCF5, 0x0009B471,
0x190AC89D, 0x5BDFB907, 0x15D4E331, 0x15D22375,
- 0x13F388D5, 0x12ACEDA5, 0x3835EA5D, 0x2587CA35, 0x06756643, 0x487C6F55,
0x65C295EB, 0x1029F2E1, 0x10CEF39D, 0x14C2E415,
- 0x444825BB, 0x24BE0A2F, 0x1D2B7C01, 0x64AE3235, 0x5D2896E5, 0x61BBBD87,
0x4A49E86D, 0x12C277FF, 0x72C81289, 0x5CF42A3D,
- 0x332FF177, 0x0DAECD23, 0x6000ED1D, 0x203CDDE1, 0x40C62CAD, 0x19B9A855,
0x782020C3, 0x6127D5BB, 0x719889A7, 0x40E4FCCF,
- 0x2A3C8FF9, 0x07411C7F, 0x3113306B, 0x4D7CA03F, 0x76119841, 0x54CEFBDF,
0x11548AB9, 0x4B0748EB, 0x569966B1, 0x45BC721B,
- 0x3D5A376B, 0x0D8923E9, 0x6D95514D, 0x0F39A367, 0x2FDAD92F, 0x721F972F,
0x42D0E21D, 0x5C5952DB, 0x7394D007, 0x02692C55,
- 0x7F92772F, 0x025F8025, 0x34347113, 0x560EA689, 0x0DCC21DF, 0x09ECC7F5,
0x091F3993, 0x0E0B52AB, 0x497CAA55, 0x0A040A49,
- 0x6D8F0CC5, 0x54F41609, 0x6E0CB8DF, 0x3DCB64C3, 0x16C365CD, 0x6D6B9FB5,
0x02B9382B, 0x6A5BFAF1, 0x1669D75F, 0x13CFD4FD,
- 0x0FDF316F, 0x21F3C463, 0x6FC58ABF, 0x04E45BE7, 0x1911225B, 0x28CD1355,
0x222084E9, 0x672AD54B, 0x476FC267, 0x6864E16D,
- 0x20AEF4FB, 0x603C5FB9, 0x55090595, 0x1113B705, 0x24E38493, 0x5291AF97,
0x5F5446D9, 0x13A6F639, 0x3D501313, 0x37E02017,
- 0x236B0ED3, 0x60F246BF, 0x01E02501, 0x2D2F66BD, 0x6BF23609, 0x16729BAF};
-
-/* IMPLEMENTATION */
-
-template <class C, class A, int S> inline Vec<C, A, S>::Vec() : n(0), i(0),
v(nullptr)
-{
- memset(static_cast<void *>(&e[0]), 0, sizeof(e));
-}
-
-template <class C, class A, int S> inline Vec<C, A, S>::Vec(const Vec<C, A, S>
&vv)
-{
- copy(vv);
-}
-
-template <class C, class A, int S> inline Vec<C, A, S>::Vec(C c)
-{
- n = 1;
- i = 0;
- v = &e[0];
- e[0] = c;
-}
-
-template <class C, class A, int S>
-inline C
-Vec<C, A, S>::get(size_t i) const
-{
- if (i < n) {
- return v[i];
- } else {
- return C();
- }
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::add(C a)
-{
- if (n & (VEC_INTEGRAL_SIZE - 1))
- v[n++] = a;
- else if (!v)
- (v = e)[n++] = a;
- else
- add_internal(a);
-}
-
-template <class C, class A, int S>
-inline C &
-Vec<C, A, S>::add()
-{
- C *ret;
- if (n & (VEC_INTEGRAL_SIZE - 1))
- ret = &v[n++];
- else if (!v)
- ret = &(v = e)[n++];
- else
- ret = &add_internal();
- return *ret;
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::drop()
-{
- if (n && 0 == --n)
- clear();
-}
-
-template <class C, class A, int S>
-inline C
-Vec<C, A, S>::pop()
-{
- if (!n)
- return 0;
- n--;
- C ret = v[n];
- if (!n)
- clear();
- return ret;
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::set_clear()
-{
- memset(v, 0, n * sizeof(C));
-}
-
-template <class C, class A, int S>
-inline C *
-Vec<C, A, S>::set_add(C a)
-{
- if (n < SET_LINEAR_SIZE) {
- for (C *c = v; c < v + n; c++)
- if (*c == a)
- return nullptr;
- add(a);
- return &v[n - 1];
- }
- if (n == SET_LINEAR_SIZE) {
- Vec<C, A, S> vv(*this);
- clear();
- for (C *c = vv.v; c < vv.v + vv.n; c++) {
- set_add_internal(*c);
- }
- }
- return set_add_internal(a);
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::set_remove(C a)
-{
- Vec<C, A, S> tmp;
- tmp.move(*this);
- for (C *c = tmp.v; c < tmp.v + tmp.n; c++)
- if (*c != a)
- set_add(a);
-}
-
-template <class C, class A, int S>
-inline size_t
-Vec<C, A, S>::count() const
-{
- int x = 0;
- for (C *c = v; c < v + n; c++)
- if (*c)
- x++;
- return x;
-}
-
-template <class C, class A, int S>
-inline C *
-Vec<C, A, S>::in(C a)
-{
- for (C *c = v; c < v + n; c++)
- if (*c == a)
- return c;
- return nullptr;
-}
-
-template <class C, class A, int S>
-inline bool
-Vec<C, A, S>::add_exclusive(C a)
-{
- if (!in(a)) {
- add(a);
- return true;
- } else
- return false;
-}
-
-template <class C, class A, int S>
-inline C *
-Vec<C, A, S>::set_in(C a)
-{
- if (n <= SET_LINEAR_SIZE)
- return in(a);
- return set_in_internal(a);
-}
-
-template <class C, class A, int S>
-inline C
-Vec<C, A, S>::first_in_set()
-{
- for (C *c = v; c < v + n; c++)
- if (*c)
- return *c;
- return 0;
-}
-
-template <class C, class A, int S>
-inline ssize_t
-Vec<C, A, S>::index(C a) const
-{
- for (C *c = v; c < v + n; c++) {
- if (*c == a) {
- return c - v;
- }
- }
- return -1;
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::move_internal(Vec<C, A, S> &vv)
-{
- n = vv.n;
- i = vv.i;
- if (vv.v == &vv.e[0]) {
- memcpy(e, &vv.e[0], sizeof(e));
- v = e;
- } else
- v = vv.v;
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::move(Vec<C, A, S> &vv)
-{
- move_internal(vv);
- vv.v = nullptr;
- vv.clear();
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::copy(const Vec<C, A, S> &vv)
-{
- n = vv.n;
- i = vv.i;
- if (vv.v == &vv.e[0]) {
- memcpy(e, &vv.e[0], sizeof(e));
- v = e;
- } else {
- if (vv.v)
- copy_internal(vv);
- else
- v = nullptr;
- }
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::fill(size_t nn)
-{
- for (size_t i = n; i < nn; i++)
- add() = 0;
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::append(const Vec<C> &vv)
-{
- for (C *c = vv.v; c < vv.v + vv.n; c++)
- if (*c != 0)
- add(*c);
-}
-
-template <class C, class A, int S>
-template <typename CountType>
-inline void
-Vec<C, A, S>::append(const C *src, CountType count)
-{
- reserve(length() + count);
- for (CountType c = 0; c < count; ++c) {
- add(src[c]);
- }
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::prepend(const Vec<C> &vv)
-{
- if (vv.n) {
- int oldn = n;
- fill(n + vv.n);
- if (oldn)
- memmove(&v[vv.n], &v[0], oldn * sizeof(v[0]));
- memcpy(&v[0], vv.v, vv.n * sizeof(v[0]));
- }
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::add_internal(C a)
-{
- addx();
- v[n++] = a;
-}
-
-template <class C, class A, int S>
-C &
-Vec<C, A, S>::add_internal()
-{
- addx();
- return v[n++];
-}
-
-template <class C, class A, int S>
-C *
-Vec<C, A, S>::set_add_internal(C c)
-{
- size_t j, k;
- if (n) {
- uintptr_t h = (uintptr_t)c;
- h = h % n;
- for (k = h, j = 0; j < i + 3; j++) {
- if (!v[k]) {
- v[k] = c;
- return &v[k];
- } else if (v[k] == c) {
- return nullptr;
- }
- k = (k + open_hash_primes[j]) % n;
- }
- }
- Vec<C, A, S> vv;
- vv.move_internal(*this);
- set_expand();
- if (vv.v) {
- set_union(vv);
- }
- return set_add(c);
-}
-
-template <class C, class A, int S>
-C *
-Vec<C, A, S>::set_in_internal(C c)
-{
- size_t j, k;
- if (n) {
- uintptr_t h = (uintptr_t)c;
- h = h % n;
- for (k = h, j = 0; j < i + 3; j++) {
- if (!v[k])
- return nullptr;
- else if (v[k] == c)
- return &v[k];
- k = (k + open_hash_primes[j]) % n;
- }
- }
- return nullptr;
-}
-
-template <class C, class A, int S>
-bool
-Vec<C, A, S>::set_union(Vec<C, A, S> &vv)
-{
- bool changed = false;
- for (size_t i = 0; i < vv.n; i++) {
- if (vv.v[i]) {
- changed = set_add(vv.v[i]) || changed;
- }
- }
- return changed;
-}
-
-template <class C, class A, int S>
-int
-Vec<C, A, S>::set_intersection(Vec<C, A, S> &vv)
-{
- Vec<C, A, S> tv;
- tv.move(*this);
- int changed = 0;
- for (int i = 0; i < tv.n; i++)
- if (tv.v[i]) {
- if (vv.set_in(tv.v[i]))
- set_add(tv.v[i]);
- else
- changed = 1;
- }
- return changed;
-}
-
-template <class C, class A, int S>
-int
-Vec<C, A, S>::some_intersection(Vec<C, A, S> &vv)
-{
- for (int i = 0; i < n; i++)
- if (v[i])
- if (vv.set_in(v[i]))
- return 1;
- return 0;
-}
-
-template <class C, class A, int S>
-int
-Vec<C, A, S>::some_disjunction(Vec<C, A, S> &vv)
-{
- for (int i = 0; i < n; i++)
- if (v[i])
- if (!vv.set_in(v[i]))
- return 1;
- for (int i = 0; i < vv.n; i++)
- if (vv.v[i])
- if (!set_in(vv.v[i]))
- return 1;
- return 0;
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::set_intersection(Vec<C, A, S> &vv, Vec<C, A, S> &result)
-{
- for (int i = 0; i < n; i++)
- if (v[i])
- if (vv.set_in(v[i]))
- result.set_add(v[i]);
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::set_disjunction(Vec<C, A, S> &vv, Vec<C, A, S> &result)
-{
- for (int i = 0; i < n; i++)
- if (v[i])
- if (!vv.set_in(v[i]))
- result.set_add(v[i]);
- for (int i = 0; i < vv.n; i++)
- if (vv.v[i])
- if (!set_in(vv.v[i]))
- result.set_add(vv.v[i]);
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::set_difference(Vec<C, A, S> &vv, Vec<C, A, S> &result)
-{
- for (int i = 0; i < n; i++)
- if (v[i])
- if (!vv.set_in(v[i]))
- result.set_add(v[i]);
-}
-
-template <class C, class A, int S>
-int
-Vec<C, A, S>::some_difference(Vec<C, A, S> &vv)
-{
- for (int i = 0; i < n; i++)
- if (v[i])
- if (!vv.set_in(v[i]))
- return 1;
- return 0;
-}
-
-template <class C, class A, int S>
-size_t
-Vec<C, A, S>::set_count() const
-{
- size_t x = 0;
- for (size_t i = 0; i < n; i++) {
- if (v[i]) {
- x++;
- }
- }
- return x;
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::set_to_vec()
-{
- C *x = &v[0], *y = x;
- for (; y < v + n; y++) {
- if (*y) {
- if (x != y)
- *x = *y;
- x++;
- }
- }
- if (i) {
- i = prime2[i]; // convert set allocation to reserve
- if (i - n > 0)
- memset(&v[n], 0, (i - n) * (sizeof(C)));
- } else {
- i = 0;
- if (v == &e[0] && VEC_INTEGRAL_SIZE - n > 0)
- memset(&v[n], 0, (VEC_INTEGRAL_SIZE - n) * (sizeof(C)));
- }
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::vec_to_set()
-{
- Vec<C, A, S> vv;
- vv.move(*this);
- for (C *c = vv.v; c < vv.v + vv.n; c++)
- set_add(*c);
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::remove_index(int index)
-{
- if (n > 1)
- memmove(&v[index], &v[index + 1], (n - 1 - index) * sizeof(v[0]));
- n--;
- if (n <= 0)
- v = e;
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::insert(size_t index, C a)
-{
- add();
- memmove(&v[index + 1], &v[index], (n - index - 1) * sizeof(C));
- v[index] = a;
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::insert(size_t index, Vec<C> &vv)
-{
- fill(n + vv.n);
- memmove(&v[index + vv.n], &v[index], (n - index - 1) * sizeof(C));
- for (int x = 0; x < vv.n; x++)
- v[index + x] = vv[x];
-}
-
-template <class C, class A, int S>
-C &
-Vec<C, A, S>::insert(size_t index)
-{
- add();
- memmove(&v[index + 1], &v[index], (n - index - 1) * sizeof(C));
- memset(&v[index], 0, sizeof(C));
- return v[index];
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::reverse()
-{
- for (int i = 0; i < n / 2; i++) {
- C *s = &v[i], *e = &v[n - 1 - i];
- C t;
- memcpy(&t, s, sizeof(t));
- memcpy(s, e, sizeof(t));
- memcpy(e, &t, sizeof(t));
- }
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::copy_internal(const Vec<C, A, S> &vv)
-{
- int l = n, nl = (1 + VEC_INITIAL_SHIFT);
- l = l >> VEC_INITIAL_SHIFT;
- while (l) {
- l = l >> 1;
- nl++;
- }
- nl = 1 << nl;
- v = (C *)A::alloc(nl * sizeof(C));
- memcpy(static_cast<void *>(v), vv.v, n * sizeof(C));
- memset(static_cast<void *>(v + n), 0, (nl - n) * sizeof(C));
- if (i > n) // reset reserve
- i = 0;
-}
-
-template <class C, class A, int S>
-void
-Vec<C, A, S>::set_expand()
-{
- if (!n)
- i = SET_INITIAL_INDEX;
- else
- i = i + 1;
- n = prime2[i];
- v = (C *)A::alloc(n * sizeof(C));
- memset(static_cast<void *>(v), 0, n * sizeof(C));
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::reserve(size_t x)
-{
- if (x <= n)
- return;
- unsigned xx = 1 << VEC_INITIAL_SHIFT;
- while (xx < x)
- xx *= 2;
- i = xx;
- void *vv = (void *)v;
- v = (C *)A::alloc(i * sizeof(C));
- if (vv && n)
- memcpy(v, vv, n * sizeof(C));
- memset(&v[n], 0, (i - n) * sizeof(C));
- if (vv && vv != e)
- A::free(vv);
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::addx()
-{
- if (!v) {
- v = e;
- return;
- }
- if (v == e) {
- v = (C *)A::alloc(VEC_INITIAL_SIZE * sizeof(C));
- memcpy(static_cast<void *>(v), &e[0], n * sizeof(C));
- ink_assert(n < VEC_INITIAL_SIZE);
- memset(static_cast<void *>(&v[n]), 0, (VEC_INITIAL_SIZE - n) * sizeof(C));
- } else {
- if ((n & (n - 1)) == 0) {
- size_t nl = n * 2;
- if (nl <= i) {
- return;
- } else {
- i = 0;
- }
- void *vv = (void *)v;
- v = (C *)A::alloc(nl * sizeof(C));
- memcpy(static_cast<void *>(v), vv, n * sizeof(C));
- memset(static_cast<void *>(&v[n]), 0, n * sizeof(C));
- A::free(vv);
- }
- }
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::reset()
-{
- v = nullptr;
- n = 0;
- i = 0;
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::clear()
-{
- if (v && v != e)
- A::free(v);
- reset();
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::free_and_clear()
-{
- for (size_t x = 0; x < (n); x++)
- A::free((void *)v[x]);
- clear();
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::delete_and_clear()
-{
- for (size_t x = 0; x < n; x++) {
- if (v[x]) {
- delete v[x];
- }
- }
- clear();
-}
-
-template <class C, class A, int S> inline Vec<C, A, S>::~Vec()
-{
- if (v && v != e)
- A::free(v);
-}
-
-template <class C, class A, int S>
-inline int
-marshal_size(Vec<C, A, S> &v)
-{
- int l = sizeof(int) * 2;
- for (int x = 0; x < v.n; x++)
- l += ::marshal_size(v.v[x]);
- return l;
-}
-
-template <class C, class A, int S>
-inline int
-marshal(Vec<C, A, S> &v, char *buf)
-{
- char *x = buf;
- *(int *)x = v.n;
- x += sizeof(int);
- *(int *)x = v.i;
- x += sizeof(int);
- for (int i = 0; i < v.n; i++)
- x += ::marshal(v.v[i], x);
- return x - buf;
-}
-
-template <class C, class A, int S>
-inline int
-unmarshal(Vec<C, A, S> &v, char *buf)
-{
- char *x = buf;
- v.n = *(int *)x;
- x += sizeof(int);
- v.i = *(int *)x;
- x += sizeof(int);
- if (v.n) {
- v.v = (C *)A::alloc(sizeof(C) * v.n);
- memset(v.v, 0, sizeof(C) * v.n);
- } else
- v.v = v.e;
- for (int i = 0; i < v.n; i++)
- x += ::unmarshal(v.v[i], x);
- return x - buf;
-}
-
-template <class C, class A, int S>
-inline int
-Vec<C, A, S>::write(int fd)
-{
- int r = 0, t = 0;
- if ((r = ::write(fd, this, sizeof(*this))) < 0)
- return r;
- t += r;
- if ((r = ::write(fd, v, n * sizeof(C))) < 0)
- return r;
- t += r;
- return t;
-}
-
-template <class C, class A, int S>
-inline int
-Vec<C, A, S>::read(int fd)
-{
- int r = 0, t = 0;
- if ((r = ::read(fd, this, sizeof(*this))) < 0)
- return r;
- t += r;
- v = (C *)A::alloc(sizeof(C) * n);
- memset(v, 0, sizeof(C) * n);
- if ((r = ::read(fd, v, n * sizeof(C))) < 0)
- return r;
- t += r;
- return t;
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::swap(C *p1, C *p2)
-{
- C t = *p1;
- *p1 = *p2;
- *p2 = t;
-}
-
-template <class C>
-inline void
-qsort_Vec(C *left, C *right, bool (*lt)(C, C))
-{
- if (right - left < 5) {
- for (C *y = right - 1; y > left; y--) {
- for (C *x = left; x < y; x++) {
- if (lt(x[1], x[0])) {
- C t = x[0];
- x[0] = x[1];
- x[1] = t;
- }
- }
- }
- } else {
- C *center = left + ((right - left) / 2);
- C median;
-
- // find the median
- if (lt(*center, *left)) { // order left and center
- Vec<C>::swap(center, left);
- }
- if (lt(*(right - 1), *left)) { // order left and right
- Vec<C>::swap(right - 1, left);
- }
- if (lt(*(right - 1), *center)) { // order right and center
- Vec<C>::swap((right - 1), center);
- }
- Vec<C>::swap(center, right - 2); // stash the median one from the right
for now
- median = *(right - 2); // the median of left, center and right
values
-
- // now partition, pivoting on the median value
- // l ptr is +1 b/c we already put the lowest of the incoming left, center
- // and right in there, ignore it for now
- // r ptr is -2 b/c we already put the biggest of the 3 values in (right-1)
- // and the median in (right -2)
- C *l = left + 1, *r = right - 2;
-
- // move l and r until they have something to do
- while (lt(median, *(r - 1))) {
- r--;
- }
- while (l < r && lt(*l, median)) {
- l++;
- }
- // until l and r meet,
- // compare l and median
- // swap l for r if l is larger than median
- while (l < r) {
- if (lt(*l, median)) {
- l++;
- } else {
- Vec<C>::swap(l, r - 1);
- r--;
- }
- }
-
- Vec<C>::swap(l, right - 2); // restore median to its rightful place
-
- // recurse for the littles (left segment)
- qsort_Vec<C>(left, l, lt);
- // recurse for the bigs (right segment)
- qsort_Vec<C>(l + 1, right, lt);
- }
-}
-
-template <class C>
-inline void
-qsort_VecRef(C *left, C *right, bool (*lt)(const C &, const C &), unsigned int
*p_ctr)
-{
- if (right - left < 5) {
- for (C *y = right - 1; y > left; y--) {
- for (C *x = left; x < y; x++) {
- if (lt(x[1], x[0])) {
- C t = x[0];
- x[0] = x[1];
- x[1] = t;
- }
- }
- }
- } else {
- C *center = left + ((right - left) / 2);
- C median;
-
- // find the median
- if (lt(*center, *left)) { // order left and center
- Vec<C>::swap(center, left);
- }
- if (lt(*(right - 1), *left)) { // order left and right
- Vec<C>::swap(right - 1, left);
- }
- if (lt(*(right - 1), *center)) { // order right and center
- Vec<C>::swap((right - 1), center);
- }
- Vec<C>::swap(center, right - 2); // stash the median one from the right
for now
- median = *(right - 2); // the median of left, center and right
values
-
- // now partition, pivoting on the median value
- // l ptr is +1 b/c we already put the lowest of the incoming left, center
- // and right in there, ignore it for now
- // r ptr is -2 b/c we already put the biggest of the 3 values in (right-1)
- // and the median in (right -2)
- C *l = left + 1, *r = right - 2;
-
- // move l and r until they have something to do
- while (lt(median, *(r - 1))) {
- r--;
- }
- while (l < r && lt(*l, median)) {
- l++;
- }
- // until l and r meet,
- // compare l and median
- // swap l for r if l is larger than median
- while (l < r) {
- if (lt(*l, median)) {
- l++;
- } else {
- Vec<C>::swap(l, r - 1);
- r--;
- }
- }
-
- Vec<C>::swap(l, right - 2); // restore median to its rightful place
-
- // recurse for the littles (left segment)
- qsort_VecRef<C>(left, l, lt, p_ctr);
- // recurse for the bigs (right segment)
- qsort_VecRef<C>(l + 1, right, lt, p_ctr);
- }
- (*p_ctr)++;
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::qsort(bool (*lt)(C, C))
-{
- if (n)
- qsort_Vec<C>(&v[0], end(), lt);
-}
-
-template <class C, class A, int S>
-inline void
-Vec<C, A, S>::qsort(bool (*lt)(const C &, const C &))
-{
- static unsigned int ctr = 0;
- if (n)
- qsort_VecRef<C>(&v[0], end(), lt, &ctr);
- Debug("qsort", "took %u iterations to sort %ld elements", ctr, n);
-}
-void test_vec();
-
-typedef const char cchar;
-
-template <class A>
-static inline char *
-_dupstr(cchar *s, cchar *e = nullptr)
-{
- int l = e ? e - s : strlen(s);
- char *ss = (char *)A::alloc(l + 1);
- memcpy(ss, s, l);
- ss[l] = 0;
- return ss;
-}
-
-// Simple direct mapped Map (pointer hash table) and Environment
-
-template <class K, class C> class MapElem
-{
-public:
- K key;
- C value;
- bool
- operator==(MapElem &e)
- {
- return e.key == key;
- }
- operator uintptr_t(void) { return (uintptr_t)(uintptr_t)key; }
- MapElem(K const &akey, C const &avalue) : key(akey), value(avalue) {}
- MapElem(MapElem const &e) : key(e.key), value(e.value) {}
- MapElem() : key(), value() {}
-};
-
-template <class K, class C, class A = DefaultAlloc> class Map : public
Vec<MapElem<K, C>, A>
-{
-public:
- typedef MapElem<K, C> ME;
- typedef Vec<ME, A> PType;
- using PType::n;
- using PType::i;
- using PType::v;
- ME *put(K akey, C avalue);
- ME *put(K akey);
- C get(K akey);
- C *getp(K akey);
- void get_keys(Vec<K> &keys) const;
- void get_keys_set(Vec<K> &keys);
- void get_values(Vec<C> &values);
- void map_union(Map<K, C> &m);
- bool some_disjunction(Map<K, C> &m) const;
-};
-
-template <class C> class HashFns
-{
-public:
- static uintptr_t hash(C a);
- static int equal(C a, C b);
-};
-
-template <class K, class C> class HashSetFns
-{
-public:
- static uintptr_t hash(C a);
- static uintptr_t hash(K a);
- static int equal(C a, C b);
- static int equal(K a, C b);
-};
-
-template <class K, class AHashFns, class C, class A = DefaultAlloc> class
HashMap : public Map<K, C, A>
-{
-public:
- typedef MapElem<K, C> value_type; ///< What's stored in the table.
- using Map<K, C, A>::n;
- using Map<K, C, A>::i;
- using Map<K, C, A>::v;
- using Map<K, C, A>::e;
- HashMap() {}
- HashMap(C c) : invalid_value(c) {}
- MapElem<K, C> *get_internal(K akey) const;
- C get(K akey) const;
- value_type *put(K akey, C avalue);
- void get_keys(Vec<K> &keys) const;
- void get_values(Vec<C> &values);
-
-private:
- C invalid_value = 0; // return this object if key is not present
-};
-
-#define form_Map(_c, _p, _v)
\
- if ((_v).n)
\
- for (_c *qq__##_p = (_c *)0, *_p = &(_v).v[0]; ((uintptr_t)(qq__##_p) <
(_v).n) && ((_p = &(_v).v[(uintptr_t)qq__##_p]) || 1); \
- qq__##_p = (_c *)(((uintptr_t)qq__##_p) + 1))
\
- if ((_p)->key)
-
-template <class K, class AHashFns, class C, class A = DefaultAlloc> class
HashSet : public Vec<C, A>
-{
-public:
- typedef Vec<C, A> V;
- using V::n;
- using V::i;
- using V::v;
- using V::e;
- C get(K akey);
- C *put(C avalue);
-};
-
-class StringHashFns
-{
-public:
- static uintptr_t
- hash(cchar *s)
- {
- uintptr_t h = 0;
- // 31 changed to 27, to avoid prime2 in vec.cpp
- while (*s)
- h = h * 27 + (unsigned char)*s++;
- return h;
- }
- static int
- equal(cchar *a, cchar *b)
- {
- return !strcmp(a, b);
- }
-};
-
-class CaseStringHashFns
-{
-public:
- static uintptr_t
- hash(cchar *s)
- {
- uintptr_t h = 0;
- // 31 changed to 27, to avoid prime2 in vec.cpp
- while (*s)
- h = h * 27 + (unsigned char)toupper(*s++);
- return h;
- }
- static int
- equal(cchar *a, cchar *b)
- {
- return !strcasecmp(a, b);
- }
-};
-
-class PointerHashFns
-{
-public:
- static uintptr_t
- hash(void *s)
- {
- return (uintptr_t)(uintptr_t)s;
- }
- static int
- equal(void *a, void *b)
- {
- return a == b;
- }
-};
-
-template <class C, class AHashFns, class A = DefaultAlloc> class ChainHash :
public Map<uintptr_t, List<C, A>, A>
-{
-public:
- using Map<uintptr_t, List<C, A>, A>::n;
- using Map<uintptr_t, List<C, A>, A>::v;
- typedef ConsCell<C, A> ChainCons;
- C put(C c);
- C get(C c);
- C put_bag(C c);
- int get_bag(C c, Vec<C> &v);
- int del(C avalue);
- void get_elements(Vec<C> &elements);
-};
-
-template <class K, class AHashFns, class C, class A = DefaultAlloc>
-class ChainHashMap : public Map<uintptr_t, List<MapElem<K, C>, A>, A>
-{
-public:
- using Map<uintptr_t, List<MapElem<K, C>, A>, A>::n;
- using Map<uintptr_t, List<MapElem<K, C>, A>, A>::v;
- MapElem<K, C> *put(K akey, C avalue);
- C get(K akey);
- int del(K akey);
- MapElem<K, C> *put_bag(K akey, C c);
- int get_bag(K akey, Vec<C> &v);
- void get_keys(Vec<K> &keys);
- void get_values(Vec<C> &values);
-};
-
-template <class F = StringHashFns, class A = DefaultAlloc> class
StringChainHash : public ChainHash<cchar *, F, A>
-{
-public:
- cchar *canonicalize(cchar *s, cchar *e);
- cchar *
- canonicalize(cchar *s)
- {
- return canonicalize(s, s + strlen(s));
- }
-};
-
-template <class C, class AHashFns, int N, class A = DefaultAlloc> class
NBlockHash
-{
-public:
- int n;
- int i;
- C *v;
- C e[N];
-
- C *
- end()
- {
- return last();
- }
- int
- length()
- {
- return N * n;
- }
- C *first();
- C *last();
- C put(C c);
- C get(C c);
- C *assoc_put(C *c);
- C *assoc_get(C *c);
- int del(C c);
- void clear();
- void reset();
- int count();
- void size(int p2);
- void copy(const NBlockHash<C, AHashFns, N, A> &hh);
- void move(NBlockHash<C, AHashFns, N, A> &hh);
- NBlockHash();
- NBlockHash(NBlockHash<C, AHashFns, N, A> &hh)
- {
- v = e;
- copy(hh);
- }
-};
-
-/* use forv_Vec on BlockHashes */
-
-#define DEFAULT_BLOCK_HASH_SIZE 4
-template <class C, class ABlockHashFns> class BlockHash : public NBlockHash<C,
ABlockHashFns, DEFAULT_BLOCK_HASH_SIZE>
-{
-};
-typedef BlockHash<cchar *, StringHashFns> StringBlockHash;
-
-template <class K, class C, class A = DefaultAlloc> class Env
-{
-public:
- typedef ConsCell<C, A> EnvCons;
- void put(K akey, C avalue);
- C get(K akey);
- void push();
- void pop();
- void
- clear()
- {
- store.clear();
- scope.clear();
- }
-
- Env() {}
- Map<K, List<C> *, A> store;
- List<List<K>, A> scope;
- List<C, A> *get_bucket(K akey);
-};
-
-/* IMPLEMENTATION */
-
-template <class K, class C, class A>
-inline C
-Map<K, C, A>::get(K akey)
-{
- MapElem<K, C> e(akey, (C)0);
- MapElem<K, C> *x = this->set_in(e);
- if (x)
- return x->value;
- return (C)0;
-}
-
-template <class K, class C, class A>
-inline C *
-Map<K, C, A>::getp(K akey)
-{
- MapElem<K, C> e(akey, (C)0);
- MapElem<K, C> *x = this->set_in(e);
- if (x)
- return &x->value;
- return 0;
-}
-
-template <class K, class C, class A>
-inline MapElem<K, C> *
-Map<K, C, A>::put(K akey, C avalue)
-{
- MapElem<K, C> e(akey, avalue);
- MapElem<K, C> *x = this->set_in(e);
- if (x) {
- x->value = avalue;
- return x;
- } else
- return this->set_add(e);
-}
-
-template <class K, class C, class A>
-inline MapElem<K, C> *
-Map<K, C, A>::put(K akey)
-{
- MapElem<K, C> e(akey, 0);
- MapElem<K, C> *x = this->set_in(e);
- if (x)
- return x;
- else
- return this->set_add(e);
-}
-
-template <class K, class C, class A>
-inline void
-Map<K, C, A>::get_keys(Vec<K> &keys) const
-{
- for (size_t i = 0; i < n; i++)
- if (v[i].key)
- keys.add(v[i].key);
-}
-
-template <class K, class C, class A>
-inline void
-Map<K, C, A>::get_keys_set(Vec<K> &keys)
-{
- for (int i = 0; i < n; i++)
- if (v[i].key)
- keys.set_add(v[i].key);
-}
-
-template <class K, class C, class A>
-inline void
-Map<K, C, A>::get_values(Vec<C> &values)
-{
- for (int i = 0; i < n; i++)
- if (v[i].key)
- values.set_add(v[i].value);
- values.set_to_vec();
-}
-
-template <class K, class C, class A>
-inline void
-Map<K, C, A>::map_union(Map<K, C> &m)
-{
- for (int i = 0; i < m.n; i++)
- if (m.v[i].key)
- put(m.v[i].key, m.v[i].value);
-}
-
-template <class K, class C, class A>
-inline bool
-Map<K, C, A>::some_disjunction(Map<K, C> &m) const
-{
- for (size_t i = 0; i < m.n; i++) {
- if (m.v[i].key && get(m.v[i].key) != m.v[i].value) {
- return true;
- }
- }
- for (size_t i = 0; i < n; i++) {
- if (v[i].key && m.get(v[i].key) != v[i].value) {
- return true;
- }
- }
- return false;
-}
-
-template <class K, class C, class A>
-inline void
-map_set_add(Map<K, Vec<C, A> *, A> &m, K akey, C avalue)
-{
- Vec<C, A> *v = m.get(akey);
- if (!v)
- m.put(akey, (v = new Vec<C, A>));
- v->set_add(avalue);
-}
-
-template <class K, class C, class A>
-inline void
-map_set_add(Map<K, Vec<C, A> *, A> &m, K akey, Vec<C> *madd)
-{
- Vec<C, A> *v = m.get(akey);
- if (!v)
- m.put(akey, (v = new Vec<C, A>));
- v->set_union(*madd);
-}
-
-template <class K, class AHashFns, class C, class A>
-inline C
-HashSet<K, AHashFns, C, A>::get(K akey)
-{
- if (!n)
- return 0;
- if (n <= MAP_INTEGRAL_SIZE) {
- for (C *c = v; c < v + n; c++)
- if (c)
- if (AHashFns::equal(akey, *c))
- return *c;
- return 0;
- }
- uintptr_t h = AHashFns::hash(akey);
- h = h % n;
- for (int k = h, j = 0; j < i + 3; j++) {
- if (!v[k])
- return 0;
- else if (AHashFns::equal(akey, v[k]))
- return v[k];
- k = (k + open_hash_primes[j]) % n;
- }
- return 0;
-}
-
-template <class K, class AHashFns, class C, class A>
-inline C *
-HashSet<K, AHashFns, C, A>::put(C avalue)
-{
- if (n < MAP_INTEGRAL_SIZE) {
- if (!v)
- v = e;
- for (int i = 0; i < n; i++)
- if (AHashFns::equal(avalue, v[i]))
- return &v[i];
- v[n] = avalue;
- n++;
- return &v[n - 1];
- }
- if (n > MAP_INTEGRAL_SIZE) {
- uintptr_t h = AHashFns::hash(avalue);
- h = h % n;
- for (int k = h, j = 0; j < i + 3; j++) {
- if (!v[k]) {
- v[k] = avalue;
- return &v[k];
- }
- k = (k + open_hash_primes[j]) % n;
- }
- } else
- i = SET_INITIAL_INDEX - 1; // will be incremented in set_expand
- HashSet<K, AHashFns, C, A> vv(*this);
- Vec<C, A>::set_expand();
- for (int i = 0; i < vv.n; i++)
- if (vv.v[i])
- put(vv.v[i]);
- return put(avalue);
-}
-
-template <class K, class AHashFns, class C, class A>
-inline MapElem<K, C> *
-HashMap<K, AHashFns, C, A>::get_internal(K akey) const
-{
- if (!n)
- return nullptr;
- if (n <= MAP_INTEGRAL_SIZE) {
- for (MapElem<K, C> *c = v; c < v + n; c++)
- if (c->key)
- if (AHashFns::equal(akey, c->key))
- return c;
- return nullptr;
- }
- uintptr_t h = AHashFns::hash(akey);
- h = h % n;
- for (size_t k = h, j = 0; j < i + 3; j++) {
- if (!v[k].key)
- return nullptr;
- else if (AHashFns::equal(akey, v[k].key))
- return &v[k];
- k = (k + open_hash_primes[j]) % n;
- }
- return nullptr;
-}
-
-template <class K, class AHashFns, class C, class A>
-inline C
-HashMap<K, AHashFns, C, A>::get(K akey) const
-{
- MapElem<K, C> *x = get_internal(akey);
- if (!x)
- return invalid_value;
- return x->value;
-}
-
-template <class K, class AHashFns, class C, class A>
-inline MapElem<K, C> *
-HashMap<K, AHashFns, C, A>::put(K akey, C avalue)
-{
- MapElem<K, C> *x = get_internal(akey);
- if (x) {
- x->value = avalue;
- return x;
- } else {
- if (n < MAP_INTEGRAL_SIZE) {
- if (!v)
- v = e;
- v[n].key = akey;
- v[n].value = avalue;
- n++;
- return &v[n - 1];
- }
- if (n > MAP_INTEGRAL_SIZE) {
- uintptr_t h = AHashFns::hash(akey);
- h = h % n;
- for (size_t k = h, j = 0; j < i + 3; j++) {
- if (!v[k].key) {
- v[k].key = akey;
- v[k].value = avalue;
- return &v[k];
- }
- k = (k + open_hash_primes[j]) % n;
- }
- } else
- i = SET_INITIAL_INDEX - 1; // will be incremented in set_expand
- }
- HashMap<K, AHashFns, C, A> vv(*this);
- Map<K, C, A>::set_expand();
- for (size_t i = 0; i < vv.n; i++) {
- if (vv.v && vv.v[i] && vv.v[i].key) {
- put(vv.v[i].key, vv.v[i].value);
- }
- }
- return put(akey, avalue);
-}
-
-template <class K, class AHashFns, class C, class A>
-inline void
-HashMap<K, AHashFns, C, A>::get_keys(Vec<K> &keys) const
-{
- Map<K, C, A>::get_keys(keys);
-}
-
-template <class K, class AHashFns, class C, class A>
-inline void
-HashMap<K, AHashFns, C, A>::get_values(Vec<C> &values)
-{
- Map<K, C, A>::get_values(values);
-}
-
-/*
----------------------------------------------------------------------------------------------
*/
-/** A hash map usable by ATS core.
-
- This class depends on the @c DLL class from @c List.h. It assumes it can
uses instances of that
- class to store chains of elements.
-
- Values stored in this container are not destroyed when the container is
destroyed. These must be
- released by the client.
-
- Duplicate keys are allowed. Clients must walk the list for multiple
entries.
- @see @c Location::operator++()
-
- By default the table automatically expands to limit the average chain
length. This can be tuned. If set
- to @c MANUAL then the table will expand @b only when explicitly requested
to do so by the client.
- @see @c ExpansionPolicy
- @see @c setExpansionPolicy()
- @see @c setExpansionLimit()
- @see @c expand()
-
- All the parameters for the hash map are passed via the template argument
@a H. This is a struct
- that contains both type definitions and static methods. It must have
-
- - No state (cheap and risk free to copy).
-
- - All required methods are static methods.
-
- @a ID is a @c typedef for the hash type. This is the type of the value
produced by the hash function. It must be
- a numeric type.
-
- @a Key is a @c typedef for the key type. This is passed to the @a hash
function and used for equality
- checking of elements. It is presumed cheap to copy. If the underlying key
is not a simple type
- then @a Key should be declared as a constant pointer or a constant
reference. The hash table
- will never attempt to modify a key.
-
- @a Value is a @c typedef for the value type, the type of the element
stored in the hash table.
-
- @a ListHead is @c typedef for the @c DLL compatible class that can serve
as the anchor for a chain of
- @a Value instances. This is use both as data to be stored in a bucket and
for access to next and
- previous pointers from instances of @a Value.
-
- Method @c hash converts a @c Key to a hash value. The key argument can be
by value or by constant reference.
- @code
- ID hash(Key key);
- @endcode
-
- Method @c key extracts the key from a @c Value instance.
- @code
- Key key(Value const*);
- @endcode
-
- Method @c equal checks for equality between a @c Key and a @c Value. The
key argument can be a
- constant reference or by value. The arguments should be @c const if not by
value.
-
- @code
- bool equal (Key lhs, Key rhs);
- bool equal (Key key, Value const* value);
- @endcode
-
- Example for @c HttpServerSession keyed by the origin server IP address.
-
- @code
- struct Hasher {
- typedef uint32_t ID;
- typedef sockaddr const* Key;
- typedef HttpServerSession Value;
- typedef DList(HttpServerSession, ip_hash_link) ListHead;
-
- static uint32_t hash(sockaddr const* key) { return ats_ip_hash(key); }
- static sockaddr const* key(HttpServerSession const* value) { return
&value->ip.sa }
- static bool equal(sockaddr const* lhs, sockaddr const* rhs) { return
ats_ip_eq(lhs, rhs); }
- // Alternatively
- // static ID hash(Key* key);
- // static Key key(Value* value);
- // static bool equal(Key lhs, Key rhs);
- @endcode
-
- In @c HttpServerSession is the definition
-
- @code
- LINK(HttpServerSession, ip_hash_link);
- @endcode
-
- which creates the internal links used by @c TSHashTable.
-
- */
-template <typename H ///< Hashing utility class.
- >
-class TSHashTable
-{
-public:
- typedef TSHashTable self; ///< Self reference type.
-
- // Make embedded types easier to use by importing them to the class
namespace.
- typedef H Hasher; ///< Rename and promote.
- typedef typename Hasher::ID ID; ///< ID type.
- typedef typename Hasher::Key Key; ///< Key type.
- typedef typename Hasher::Value Value; ///< Stored value (element) type.
- typedef typename Hasher::ListHead ListHead; ///< Anchor for chain.
-
- /// When the hash table is expanded.
- enum ExpansionPolicy {
- MANUAL, ///< Client must explicitly expand the table.
- AVERAGE, ///< Table expands if average chain length exceeds limit.
[default]
- MAXIMUM ///< Table expands if any chain length exceeds limit.
- };
-
- /** Hash bucket.
- This is stored in the base array, anchoring the open chaining.
-
- @internal The default values are selected so that zero initialization is
correct. Be careful if you
- change that.
- */
- struct Bucket {
- ListHead m_chain; ///< Chain of elements.
- size_t m_count; ///< # of elements in chain.
-
- /** Internal chain for iteration.
-
- Iteration is tricky because it needs to skip over empty buckets and
detect end of buckets.
- Both of these are difficult inside the iterator without excess data.
So we chain the
- non-empty buckets and let the iterator walk that. This makes end
detection easy and
- iteration on sparse data fast. If we make it a doubly linked list
adding and removing buckets
- is very fast as well.
- */
- LINK(Bucket, m_link);
-
- /** Do the values in this bucket have different keys?
-
- @internal This can have a false positive, but that's OK, better than
the expense of being
- exact. What we want is to avoid expanding to shorten the chain if it
won't help, which it
- won't if all the keys are the same.
-
- @internal Because we've selected the default to be @c false so we can
use @c Vec which zero fills empty elements.
- */
- bool m_mixed_p;
-
- /// Default constructor - equivalent to zero filled.
- Bucket() : m_count(0), m_mixed_p(false) { ink_zero(m_link); }
- };
-
- /** Information about locating a value in the hash table.
-
- An instance of this returned when searching for a key in the table. It
can then be used to
- check if a matching key was found, and to iterate over equivalent keys.
Note this iterator
- will touch only values which have a matching key.
-
- @internal It's not really an iterator, although similar.
- @internal we store the ID (hashed key value) for efficiency - we can get
the actual key via the
- @a m_value member.
- */
- struct Location {
- Value *m_value; ///< The value located.
- Bucket *m_bucket; ///< Containing bucket of value.
- ID m_id; ///< ID (hashed key).
- size_t m_distance; ///< How many values in the chain we've gone past to
get here.
-
- /// Default constructor - empty location.
- Location() : m_value(nullptr), m_bucket(nullptr), m_id(0), m_distance(0) {}
- /// Check for location being valid (referencing a value).
- bool
- isValid() const
- {
- return nullptr != m_value;
- }
-
- /// Automatically cast to a @c Value* for convenience.
- /// @note This lets you assign the return of @c find to a @c Value*.
- /// @note This also permits the use of this class directly as a boolean
expression.
- operator Value *() const { return m_value; }
- /// Dereference.
- Value &operator*() const { return *m_value; }
- /// Dereference.
- Value *operator->() const { return m_value; }
- /// Find next value with matching key (prefix).
- Location &
- operator++()
- {
- if (m_value)
- this->advance();
- return *this;
- }
- /// Find next value with matching key (postfix).
- Location &
- operator++(int)
- {
- Location zret(*this);
- if (m_value)
- this->advance();
- return zret;
- }
-
- protected:
- /// Move to next matching value, no checks.
- void advance();
-
- friend class TSHashTable;
- };
-
- /** Standard iterator for walking the table.
- This iterates over all elements.
- @internal Iterator is @a end if @a m_value is @c nullptr.
- */
- struct iterator {
- Value *m_value; ///< Current location.
- Bucket *m_bucket; ///< Current bucket;
-
- iterator() : m_value(0), m_bucket(0) {}
- iterator &operator++();
- iterator operator++(int);
- Value &operator*() { return *m_value; }
- Value *operator->() { return m_value; }
- bool
- operator==(iterator const &that)
- {
- return m_bucket == that.m_bucket && m_value == that.m_value;
- }
- bool
- operator!=(iterator const &that)
- {
- return !(*this == that);
- }
-
- protected:
- /// Internal iterator constructor.
- iterator(Bucket *b, Value *v) : m_value(v), m_bucket(b) {}
- friend class TSHashTable;
- };
-
- iterator begin(); ///< First element.
- iterator end(); ///< Past last element.
-
- /// The default starting number of buckets.
- static size_t const DEFAULT_BUCKET_COUNT = 7; ///< POOMA.
- /// The default expansion policy limit.
- static size_t const DEFAULT_EXPANSION_LIMIT = 4; ///< Value from previous
version.
-
- /** Constructor (also default).
- Constructs an empty table with at least @a nb buckets.
- */
- TSHashTable(size_t nb = DEFAULT_BUCKET_COUNT);
-
- /** Insert a value in to the table.
- The @a value must @b NOT already be in a table of this type.
- @note The value itself is put in the table, @b not a copy.
- */
- void insert(Value *value);
-
- /** Find a value that matches @a key.
-
- @note This finds the first value with a matching @a key. No other
properties
- of the value are examined.
-
- @return The @c Location of the value. Use @c Location::isValid() to
check for success.
- */
- Location find(Key key);
-
- /** Get a @c Location for @a value.
-
- This is a bit obscure but needed in certain cases. It should only be
used on a @a value that
- is already known to be in the table. It just does the bucket lookup and
uses that and the @a
- value to construct a @c Location that can be used with other methods.
The @a m_distance value
- is not set in this case for performance reasons.
- */
- Location find(Value *value);
-
- /** Remove the value at @a location from the table.
-
- This method assumes a @a location is consistent. Be very careful if you
modify a @c Location.
-
- @note This does @b not clean up the removed elements. Use carefully to
avoid leaks.
-
- @return @c true if the value was removed, @c false otherwise.
- */
- bool remove(Location const &location);
-
- /** Remove @b all values with @a key.
-
- @note This does @b not clean up the removed elements. Use carefully to
avoid leaks.
-
- @return @c true if any value was removed, @c false otherwise.
- */
- bool remove(Key key);
-
- /** Remove all values from the table.
-
- The values are not cleaned up. The values are not touched in this
method, therefore it is safe
- to destroy them first and then @c clear this table.
- */
- void clear();
-
- /// Get the number of elements in the table.
- size_t
- count() const
- {
- return m_count;
- }
-
- /// Get the number of buckets in the table.
- size_t
- bucketCount() const
- {
- return m_array.n;
- }
-
- /// Enable or disable expanding the table when chains are long.
- void
- setExpansionPolicy(ExpansionPolicy p)
- {
- m_expansion_policy = p;
- }
- /// Get the current expansion policy.
- ExpansionPolicy
- getExpansionPolicy() const
- {
- return m_expansion_policy;
- }
- /// Set the limit value for the expansion policy.
- void
- setExpansionLimit(size_t n)
- {
- m_expansion_limit = n;
- }
- /// Set the limit value for the expansion policy.
- size_t
- expansionLimit() const
- {
- return m_expansion_limit;
- }
-
- /** Expand the hash.
-
- Useful primarily when the expansion policy is set to @c MANUAL.
- */
- void expand();
-
-protected:
- typedef Vec<Bucket, DefaultAlloc, 0> Array; ///< Bucket array.
-
- size_t m_count; ///< # of elements stored in the table.
- ExpansionPolicy m_expansion_policy; ///< When to exand the table.
- size_t m_expansion_limit; ///< Limit value for expansion.
- Array m_array; ///< Bucket storage.
- /// Make available to nested classes statically.
- // We must reach inside the link hackery because we're in a template and
- // must use typename. Older compilers don't handle typename outside of
- // template context so if we put typename in the base definition it won't
- // work in non-template classes.
- typedef DLL<Bucket, typename Bucket::Link_m_link> BucketChain;
- /// List of non-empty buckets.
- BucketChain m_bucket_chain;
-
- /** Get the ID and bucket for key.
- Fills @a m_id and @a m_bucket in @a location from @a key.
- */
- void findBucket(Key key, Location &location);
-
- // noncopyable
- TSHashTable(const TSHashTable &) = delete;
- TSHashTable &operator=(const TSHashTable &) = delete;
-};
-
-template <typename H>
-typename TSHashTable<H>::iterator
-TSHashTable<H>::begin()
-{
- // Get the first non-empty bucket, if any.
- Bucket *b = m_bucket_chain.head;
- return b && b->m_chain.head ? iterator(b, b->m_chain.head) : this->end();
-}
-
-template <typename H>
-typename TSHashTable<H>::iterator
-TSHashTable<H>::end()
-{
- return iterator(nullptr, nullptr);
-}
-
-template <typename H>
-typename TSHashTable<H>::iterator &
-TSHashTable<H>::iterator::operator++()
-{
- if (m_value) {
- if (nullptr == (m_value = ListHead::next(m_value))) { // end of
bucket, next bucket.
- if (nullptr != (m_bucket = BucketChain::next(m_bucket))) { // found
non-empty next bucket.
- m_value = m_bucket->m_chain.head;
- ink_assert(m_value); // if bucket is in chain, must be non-empty.
- }
- }
- }
- return *this;
-}
-
-template <typename H>
-typename TSHashTable<H>::iterator
-TSHashTable<H>::iterator::operator++(int)
-{
- iterator prev(*this);
- ++*this;
- return prev;
-}
-
-template <typename H>
-TSHashTable<H>::TSHashTable(size_t nb) : m_count(0),
m_expansion_policy(AVERAGE), m_expansion_limit(DEFAULT_EXPANSION_LIMIT)
-{
- if (nb) {
- int idx = 1;
- while (prime2[idx] < nb)
- ++idx;
- m_array.n = 1; // anything non-zero.
- m_array.i = idx - 1;
- }
- m_array.set_expand();
-}
-
-template <typename H>
-void
-TSHashTable<H>::Location::advance()
-{
- Key key = Hasher::key(m_value);
- // assumes valid location with correct key, advance to next matching key or
make location invalid.
- do {
- ++m_distance;
- m_value = ListHead::next(m_value);
- } while (m_value && !Hasher::equal(key, Hasher::key(m_value)));
-}
-
-template <typename H>
-void
-TSHashTable<H>::findBucket(Key key, Location &location)
-{
- location.m_id = Hasher::hash(key);
- location.m_bucket = &(m_array[location.m_id % m_array.n]);
-}
-
-template <typename H>
-typename TSHashTable<H>::Location
-TSHashTable<H>::find(Key key)
-{
- Location zret;
- Value *v;
-
- this->findBucket(key, zret); // zret gets updated to match the bucket.
- v = zret.m_bucket->m_chain.head;
- // Search for first matching key.
- while (nullptr != v && !Hasher::equal(key, Hasher::key(v)))
- v = ListHead::next(v);
- zret.m_value = v;
- return zret;
-}
-
-template <typename H>
-typename TSHashTable<H>::Location
-TSHashTable<H>::find(Value *value)
-{
- Location zret;
- this->findBucket(Hasher::key(value), zret);
- if (zret.m_bucket->m_chain.in(value)) // just checks value links and chain
head.
- zret.m_value = value;
- return zret;
-}
-
-template <typename H>
-void
-TSHashTable<H>::insert(Value *value)
-{
- Key key = Hasher::key(value);
- Bucket *bucket = &(m_array[Hasher::hash(key) % m_array.n]);
-
- // Bad client if already in a list!
- ink_assert(!bucket->m_chain.in(value));
-
- // Mark mixed if not already marked and we're adding a different key.
- if (!bucket->m_mixed_p && !bucket->m_chain.empty() && !Hasher::equal(key,
Hasher::key(bucket->m_chain.head)))
- bucket->m_mixed_p = true;
-
- bucket->m_chain.push(value);
- ++m_count;
- if (1 == ++(bucket->m_count)) // not empty, put it on the non-empty list.
- m_bucket_chain.push(bucket);
- // auto expand if appropriate.
- if ((AVERAGE == m_expansion_policy && (m_count / m_array.n) >
m_expansion_limit) ||
- (MAXIMUM == m_expansion_policy && bucket->m_count > m_expansion_limit &&
bucket->m_mixed_p))
- this->expand();
-}
-
-template <typename H>
-bool
-TSHashTable<H>::remove(Location const &l)
-{
- bool zret = false;
- if (l.isValid()) {
- ink_assert(l.m_bucket->m_count);
- ink_assert(l.m_bucket->m_chain.head);
- l.m_bucket->m_chain.remove(l.m_value);
- --m_count;
- --(l.m_bucket->m_count);
- if (0 == l.m_bucket->m_count) // if it's now empty, take it out of the
non-empty bucket chain.
- m_bucket_chain.remove(l.m_bucket);
- else if (1 == l.m_bucket->m_count) // if count drops to 1, then it's not
mixed any more.
- l.m_bucket->m_mixed_p = false;
- zret = true;
- }
- return zret;
-}
-
-template <typename H>
-bool
-TSHashTable<H>::remove(Key key)
-{
- Location loc = this->find(key);
- bool zret = loc.isValid();
- while (loc.isValid()) {
- Location target(loc);
- loc.advance();
- this->remove(target);
- }
- return zret;
-}
-
-template <typename H>
-void
-TSHashTable<H>::clear()
-{
- Bucket null_bucket;
- // Remove the values but not the actual buckets.
- for (size_t i = 0; i < m_array.n; ++i) {
- m_array[i] = null_bucket;
- }
- // Clear container data.
- m_count = 0;
- m_bucket_chain.clear();
-}
-
-template <typename H>
-void
-TSHashTable<H>::expand()
-{
- Bucket *b = m_bucket_chain.head; // stash before
reset.
- ExpansionPolicy org_expansion_policy = m_expansion_policy;
- Array tmp;
- tmp.move(m_array); // stash the current array here.
- // Reset to empty state.
- m_count = 0;
- m_bucket_chain.clear();
-
- // Because we moved the array, we have to copy back a couple of things to
make
- // the expansion actually expand. How this is supposed to work without leaks
or
- // mucking about in the internal is unclear to me.
- m_array.n = 1; // anything non-zero.
- m_array.i = tmp.i; // set the base index.
- m_array.set_expand(); // bumps array size up to next index value.
-
- m_expansion_policy = MANUAL; // disable any auto expand while we're
expanding.
- // Move the values from the stashed array to the expanded hash.
- while (b) {
- Value *v = b->m_chain.head;
- while (v) {
- b->m_chain.remove(v); // clear local pointers to be safe.
- this->insert(v);
- v = b->m_chain.head; // next value, because previous was removed.
- }
- b = BucketChain::next(b); // these buckets are in the stashed array so
pointers are still valid.
- }
- // stashed array gets cleaned up when @a tmp goes out of scope.
- m_expansion_policy = org_expansion_policy; // reset to original value.
-}
-
-/*
----------------------------------------------------------------------------------------------
*/
diff --git a/iocore/net/P_SNIActionPerformer.h
b/iocore/net/P_SNIActionPerformer.h
index 488c1cd..739abbb 100644
--- a/iocore/net/P_SNIActionPerformer.h
+++ b/iocore/net/P_SNIActionPerformer.h
@@ -98,7 +98,7 @@ class SNI_IpAllow : public ActionItem
IpMap ip_map;
public:
- SNI_IpAllow(std::string const &ip_allow_list, cchar *servername)
+ SNI_IpAllow(std::string const &ip_allow_list, const char *servername)
{
// the server identified by item.fqdn requires ATS to do IP filtering
if (ip_allow_list.length()) {
@@ -147,5 +147,5 @@ class SNIActionPerformer
{
public:
SNIActionPerformer() = default;
- static int PerformAction(Continuation *cont, cchar *servername);
+ static int PerformAction(Continuation *cont, const char *servername);
};
diff --git a/iocore/net/P_SSLConfig.h b/iocore/net/P_SSLConfig.h
index aa86ad9..b67944b 100644
--- a/iocore/net/P_SSLConfig.h
+++ b/iocore/net/P_SSLConfig.h
@@ -127,7 +127,7 @@ struct SSLConfigParams : public ConfigInfo {
mutable ink_mutex ctxMapLock;
SSL_CTX *getClientSSL_CTX(void) const;
- SSL_CTX *getNewCTX(cchar *client_cert, cchar *key_file) const;
+ SSL_CTX *getNewCTX(const char *client_cert, const char *key_file) const;
void initialize();
void cleanup();
diff --git a/iocore/net/P_SSLNetProcessor.h b/iocore/net/P_SSLNetProcessor.h
index b90266b..4b15f00 100644
--- a/iocore/net/P_SSLNetProcessor.h
+++ b/iocore/net/P_SSLNetProcessor.h
@@ -42,7 +42,6 @@
#include "P_Net.h"
#include "P_SSLConfig.h"
#include <openssl/ssl.h>
-#include "tscore/Map.h"
class UnixNetVConnection;
struct NetAccept;
diff --git a/iocore/net/P_SSLSNI.h b/iocore/net/P_SSLSNI.h
index 05318a7..c6545ab 100644
--- a/iocore/net/P_SSLSNI.h
+++ b/iocore/net/P_SSLSNI.h
@@ -60,13 +60,13 @@ struct SNIConfigParams : public ConfigInfo {
NextHopPropertyTable next_hop_table;
NextHopPropertyTable wild_next_hop_table;
YamlSNIConfig Y_sni;
- NextHopProperty *getPropertyConfig(cchar *servername) const;
+ NextHopProperty *getPropertyConfig(const char *servername) const;
SNIConfigParams();
~SNIConfigParams() override;
void cleanup();
int Initialize();
void loadSNIConfig();
- actionVector *get(cchar *servername) const;
+ actionVector *get(const char *servername) const;
void printSNImap() const;
};
diff --git a/iocore/net/SNIActionPerformer.cc b/iocore/net/SNIActionPerformer.cc
index fa5116e..842345e 100644
--- a/iocore/net/SNIActionPerformer.cc
+++ b/iocore/net/SNIActionPerformer.cc
@@ -38,7 +38,7 @@
extern std::unordered_map<int, SSLNextProtocolSet *> snpsMap;
int
-SNIActionPerformer::PerformAction(Continuation *cont, cchar *servername)
+SNIActionPerformer::PerformAction(Continuation *cont, const char *servername)
{
SNIConfig::scoped_config params;
auto actionvec = params->get(servername);
diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc
index 4948a2d..ba03ba4 100644
--- a/iocore/net/SSLConfig.cc
+++ b/iocore/net/SSLConfig.cc
@@ -473,7 +473,7 @@ SSLConfigParams::initialize()
// creates a new context attaching the provided certificate
SSL_CTX *
-SSLConfigParams::getNewCTX(cchar *client_cert, cchar *client_key) const
+SSLConfigParams::getNewCTX(const char *client_cert, const char *client_key)
const
{
SSL_CTX *nclient_ctx = nullptr;
nclient_ctx = SSLInitClientContext(this);
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index 8790883..c16d52d 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -999,7 +999,7 @@ SSLNetVConnection::sslStartHandShake(int event, int &err)
// Making the check here instead of later, so we only
// do this setting immediately after we create the SSL object
SNIConfig::scoped_config sniParam;
- cchar *serverKey = this->options.sni_servername;
+ const char *serverKey = this->options.sni_servername;
if (!serverKey) {
ats_ip_ntop(this->get_remote_addr(), buff, INET6_ADDRSTRLEN);
serverKey = buff;
diff --git a/iocore/net/SSLSNIConfig.cc b/iocore/net/SSLSNIConfig.cc
index aa963a3..ad988c8 100644
--- a/iocore/net/SSLSNIConfig.cc
+++ b/iocore/net/SSLSNIConfig.cc
@@ -43,7 +43,7 @@ extern TunnelHashMap TunnelMap;
NextHopProperty::NextHopProperty() {}
NextHopProperty *
-SNIConfigParams::getPropertyConfig(cchar *servername) const
+SNIConfigParams::getPropertyConfig(const char *servername) const
{
if (auto it = next_hop_table.find(servername); it != next_hop_table.end()) {
return it->second;
@@ -60,7 +60,7 @@ SNIConfigParams::loadSNIConfig()
for (const auto &item : Y_sni.items) {
actionVector *aiVec = new actionVector();
Debug("ssl", "name: %s", item.fqdn.data());
- cchar *servername = item.fqdn.data();
+ const char *servername = item.fqdn.data();
ats_wildcard_matcher w_Matcher;
auto wildcard = w_Matcher.match(servername);
@@ -87,9 +87,9 @@ SNIConfigParams::loadSNIConfig()
aiVec->push_back(ai3);
// set the next hop properties
SSLConfig::scoped_config params;
- auto clientCTX = params->getClientSSL_CTX();
- cchar *certFile = item.client_cert.data();
- cchar *keyFile = item.client_key.data();
+ auto clientCTX = params->getClientSSL_CTX();
+ const char *certFile = item.client_cert.data();
+ const char *keyFile = item.client_key.data();
if (certFile) {
clientCTX = params->getNewCTX(certFile, keyFile);
}
@@ -114,7 +114,7 @@ int SNIConfig::configid = 0;
SNIConfigParams::SNIConfigParams() {}
actionVector *
-SNIConfigParams::get(cchar *servername) const
+SNIConfigParams::get(const char *servername) const
{
auto action_it = sni_action_map.find(servername);
if (action_it != sni_action_map.end()) {
diff --git a/iocore/net/SSLSessionCache.h b/iocore/net/SSLSessionCache.h
index 548359b..f1ccbe3 100644
--- a/iocore/net/SSLSessionCache.h
+++ b/iocore/net/SSLSessionCache.h
@@ -21,7 +21,6 @@
#pragma once
-#include "tscore/Map.h"
#include "tscore/List.h"
#include "tscore/ink_mutex.h"
#include "P_EventSystem.h"
diff --git a/src/tscore/Makefile.am b/src/tscore/Makefile.am
index 0ab5015..d3a312c 100644
--- a/src/tscore/Makefile.am
+++ b/src/tscore/Makefile.am
@@ -170,7 +170,6 @@ libtscore_la_SOURCES = \
List.h \
llqueue.cc \
lockfile.cc \
- Map.h \
MatcherUtils.cc \
MatcherUtils.h \
MemSpan.h \
@@ -257,7 +256,6 @@ test_tscore_SOURCES = \
unit_tests/test_IntrusivePtr.cc \
unit_tests/test_IpMap.cc \
unit_tests/test_layout.cc \
- unit_tests/test_Map.cc \
unit_tests/test_List.cc \
unit_tests/test_MemArena.cc \
unit_tests/test_MT_hashtable.cc \
@@ -266,8 +264,7 @@ test_tscore_SOURCES = \
unit_tests/test_Regex.cc \
unit_tests/test_Scalar.cc \
unit_tests/test_scoped_resource.cc \
- unit_tests/test_ts_file.cc \
- unit_tests/test_Vec.cc
+ unit_tests/test_ts_file.cc
CompileParseRules_SOURCES = CompileParseRules.cc
diff --git a/src/tscore/suppression.txt b/src/tscore/suppression.txt
index d76f93e..7e7e361 100644
--- a/src/tscore/suppression.txt
+++ b/src/tscore/suppression.txt
@@ -1,4 +1,3 @@
leak:CRYPTO_malloc
leak:CRYPTO_realloc
leak:ConsCell
-leak:Vec<MapElem<char const*, int>, DefaultAlloc, 2>::set_expand
diff --git a/src/tscore/unit_tests/test_Map.cc
b/src/tscore/unit_tests/test_Map.cc
deleted file mode 100644
index a0a9886..0000000
--- a/src/tscore/unit_tests/test_Map.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-/** @file
-
- Test code for the Map templates.
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-#include "catch.hpp"
-
-#include <cstdint>
-#include "tscore/Map.h"
-#include <list>
-
-using cchar = const char;
-
-struct Item {
- LINK(Item, m_link);
- struct Hash {
- using ID = uint32_t;
- using Key = uint32_t;
- using Value = Item;
- using ListHead = DLL<Item, Item::Link_m_link>;
-
- static ID
- hash(Key key)
- {
- return key;
- }
- static Key key(Value *);
- static bool equal(Key lhs, Key rhs);
- };
-
- uint32_t _key;
- uint32_t _value;
-
- Item(uint32_t x) : _key(x), _value(x) {}
- Item(uint32_t key, uint32_t value) : _key(key), _value(value) {}
-};
-
-uint32_t
-Item::Hash::key(Value *v)
-{
- return v->_key;
-}
-bool
-Item::Hash::equal(Key lhs, Key rhs)
-{
- return lhs == rhs;
-}
-
-using Table = TSHashTable<Item::Hash>;
-
-class testHashMap
-{
-private:
- HashMap<cchar *, StringHashFns, int> testsh;
-
-public:
- int
- get(cchar *ch) const
- {
- return testsh.get(ch);
- }
-
- void
- put(cchar *key, int v)
- {
- testsh.put(key, v);
- }
-};
-
-TEST_CASE("test Map", "[libts][Map]")
-{
- typedef Map<cchar *, cchar *> SSMap;
- typedef MapElem<cchar *, cchar *> SSMapElem;
- testHashMap testsh;
-#define form_SSMap(_p, _v) form_Map(SSMapElem, _p, _v)
- SSMap ssm;
- ssm.put("a", "A");
- ssm.put("b", "B");
- ssm.put("c", "C");
- ssm.put("d", "D");
- form_SSMap(x, ssm)
- { /* nop */
- }
-
- /*
- if ((ssm).n)
- for (SSMapElem *qq__x = (SSMapElem*)0, *x = &(ssm).v[0];
- ((intptr_t)(qq__x) < (ssm).n) && ((x =
&(ssm).v[(intptr_t)qq__x]) || 1);
- qq__x = (SSMapElem*)(((intptr_t)qq__x) + 1))
- if ((x)->key) {
- // nop
- }
- */
-
- cchar *hi = "hi", *ho = "ho", *hum = "hum", *hhi = "hhi";
-
- ++hhi;
- HashMap<cchar *, StringHashFns, int> sh;
- sh.put(hi, 1);
- sh.put(ho, 2);
- sh.put(hum, 3);
- sh.put(hhi, 4);
- REQUIRE(sh.get(hi) == 4);
- REQUIRE(sh.get(ho) == 2);
- REQUIRE(sh.get(hum) == 3);
- sh.put("aa", 5);
- sh.put("ab", 6);
- sh.put("ac", 7);
- sh.put("ad", 8);
- sh.put("ae", 9);
- sh.put("af", 10);
- REQUIRE(sh.get(hi) == 4);
- REQUIRE(sh.get(ho) == 2);
- REQUIRE(sh.get(hum) == 3);
- REQUIRE(sh.get("af") == 10);
- REQUIRE(sh.get("ac") == 7);
-
- HashMap<cchar *, StringHashFns, int> sh2(-99); // return -99 if key not found
- sh2.put("aa", 15);
- sh2.put("ab", 16);
- testsh.put("aa", 15);
- testsh.put("ab", 16);
- REQUIRE(sh2.get("aa") == 15);
- REQUIRE(sh2.get("ac") == -99);
- REQUIRE(testsh.get("aa") == 15);
-
- // test_TSHashTable
- static uint32_t const N = 270;
- Table t;
- Item *item = nullptr;
- Table::Location loc;
- std::list<Item *> to_delete;
-
- for (uint32_t i = 1; i <= N; ++i) {
- item = new Item(i);
- t.insert(item);
- to_delete.push_back(item);
- }
-
- int failures = 0;
- for (uint32_t i = 1; i <= N; ++i) {
- Table::Location l = t.find(i);
- if (!l.isValid() || i != l->_value) {
- failures++;
- }
- }
- REQUIRE(failures == 0);
-
- REQUIRE(!(t.find(N * 2).isValid()));
-
- loc = t.find(N / 2 | 1);
- if (loc) {
- t.remove(loc);
- } else {
- REQUIRE(!"Did not find expected value");
- }
-
- if (!loc) {
- ; // compiler check.
- }
-
- REQUIRE(!(t.find(N / 2 | 1).isValid()));
-
- for (uint32_t i = 1; i <= N; i += 2) {
- t.remove(i);
- }
-
- failures = 0;
- for (uint32_t i = 1; i <= N; ++i) {
- Table::Location l = t.find(i);
- if (1 & i) {
- if (l.isValid()) {
- failures++;
- }
- } else {
- if (!l.isValid()) {
- failures++;
- }
- }
- }
- REQUIRE(failures == 0);
-
- int n = 0;
- failures = 0;
- for (Table::iterator spot = t.begin(), limit = t.end(); spot != limit;
++spot) {
- ++n;
- if ((spot->_value & 1) != 0) {
- failures++;
- }
- }
- REQUIRE(failures == 0);
- REQUIRE(n == N / 2);
-
- for (auto it : to_delete) {
- delete it;
- }
-}
diff --git a/src/tscore/unit_tests/test_Vec.cc
b/src/tscore/unit_tests/test_Vec.cc
deleted file mode 100644
index 0ae6af6..0000000
--- a/src/tscore/unit_tests/test_Vec.cc
+++ /dev/null
@@ -1,388 +0,0 @@
-/* -*-Mode: c++;-*-
- Various vector related code.
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/* UnionFind after Tarjan */
-
-#include "catch.hpp"
-
-#include <cstdint>
-#include <cstdio>
-#include "tscore/ink_assert.h"
-#include "tscore/Map.h"
-
-// Intervals store sets in interval format (e.g. [1..10][12..12]).
-// Inclusion test is by binary search on intervals.
-// Deletion is not supported
-class Intervals : public Vec<int>
-{
-public:
- void insert(int n);
- bool in(int n) const;
-};
-
-// UnionFind supports fast unify and finding of
-// 'representitive elements'.
-// Elements are numbered from 0 to N-1.
-class UnionFind : public Vec<int>
-{
-public:
- // set number of elements, initialized to singletons, may be called
repeatedly to increase size
- void size(int n);
- // return representitive element
- int find(int n);
- // unify the sets containing the two elements
- void unify(int n, int m);
-};
-
-// binary search over intervals
-static int
-i_find(const Intervals *i, int x)
-{
- ink_assert(i->n);
- int l = 0, h = i->n;
-Lrecurse:
- if (h <= l + 2) {
- if (h <= l) {
- return -(l + 1);
- }
- if (x < i->v[l] || x > i->v[l + 1]) {
- return -(l + 1);
- }
- return h;
- }
- int m = (((h - l) / 4) * 2) + l;
- if (x > i->v[m + 1]) {
- l = m;
- goto Lrecurse;
- }
- if (x < i->v[m]) {
- h = m;
- goto Lrecurse;
- }
- return (l + 1);
-}
-
-bool
-Intervals::in(int x) const
-{
- if (!n) {
- return false;
- }
- if (i_find(this, x) > 0) {
- return true;
- }
- return false;
-}
-
-// insert into interval with merge
-void
-Intervals::insert(int x)
-{
- if (!n) {
- add(x);
- add(x);
- return;
- }
- int l = i_find(this, x);
- if (l > 0) {
- return;
- }
- l = -l - 1;
-
- if (x > v[l + 1]) {
- if (x == v[l + 1] + 1) {
- v[l + 1]++;
- goto Lmerge;
- }
- l += 2;
- if (l < (int)n) {
- if (x == v[l] - 1) {
- v[l]--;
- goto Lmerge;
- }
- }
- goto Lmore;
- } else {
- ink_assert(x < v[l]);
- if (x == v[l] - 1) {
- v[l]--;
- goto Lmerge;
- }
- if (!l) {
- goto Lmore;
- }
- l -= 2;
- if (x == v[l + 1] + 1) {
- v[l + 1]++;
- goto Lmerge;
- }
- }
-Lmore:
- fill(n + 2);
- if (n - 2 - l > 0) {
- memmove(v + l + 2, v + l, sizeof(int) * (n - 2 - l));
- }
- v[l] = x;
- v[l + 1] = x;
- return;
-Lmerge:
- if (l) {
- if (v[l] - v[l - 1] < 2) {
- l -= 2;
- goto Ldomerge;
- }
- }
- if (l < (int)(n - 2)) {
- if (v[l + 2] - v[l + 1] < 2) {
- goto Ldomerge;
- }
- }
- return;
-Ldomerge:
- memmove(v + l + 1, v + l + 3, sizeof(int) * (n - 3 - l));
- n -= 2;
- goto Lmerge;
-}
-
-void
-UnionFind::size(int s)
-{
- size_t nn = n;
- fill(s);
- for (size_t i = nn; i < n; i++) {
- v[i] = -1;
- }
-}
-
-int
-UnionFind::find(int n)
-{
- int i, t;
- for (i = n; v[i] >= 0; i = v[i]) {
- ;
- }
- while (v[n] >= 0) {
- t = n;
- n = v[n];
- v[t] = i;
- }
- return i;
-}
-
-void
-UnionFind::unify(int n, int m)
-{
- n = find(n);
- m = find(m);
- if (n != m) {
- if (v[m] < v[n]) {
- v[m] += (v[n] - 1);
- v[n] = m;
- } else {
- v[n] += (v[m] - 1);
- v[m] = n;
- }
- }
-}
-
-TEST_CASE("test append", "[Vec]")
-{
- static const char value[] = "this is a string";
- unsigned int len = (int)sizeof(value) - 1;
-
- Vec<char> str;
-
- str.append(value, 0);
- REQUIRE(str.length() == 0);
-
- str.append(value, len);
- REQUIRE(memcmp(&str[0], value, len) == 0);
- REQUIRE(str.length() == len);
-
- str.clear();
- REQUIRE(str.length() == 0);
-
- int failures = 0;
- for (unsigned i = 0; i < 1000; ++i) {
- str.append(value, len);
- if (memcmp(&str[i * len], value, len) != 0) {
- failures++;
- }
- }
- REQUIRE(failures == 0);
-
- REQUIRE(str.length() == 1000 * len);
-}
-
-TEST_CASE("test basic", "[libts][Vec]")
-{
- Vec<void *> v, vv, vvv;
- int tt = 99 * 50, t = 0;
-
- for (size_t i = 0; i < 100; i++) {
- v.add((void *)(intptr_t)i);
- }
- for (size_t i = 0; i < 100; i++) {
- t += (int)(intptr_t)v.v[i];
- }
- REQUIRE(t == tt);
-
- t = 0;
- for (size_t i = 1; i < 100; i++) {
- vv.set_add((void *)(intptr_t)i);
- }
- for (size_t i = 1; i < 100; i++) {
- vvv.set_add((void *)(intptr_t)i);
- }
- for (size_t i = 1; i < 100; i++) {
- vvv.set_add((void *)(intptr_t)(i * 1000));
- }
- vv.set_union(vvv);
- for (size_t i = 0; i < vv.n; i++) {
- if (vv.v[i]) {
- t += (int)(intptr_t)vv.v[i];
- }
- }
- REQUIRE(t == tt + 1000 * tt);
-
- v.clear();
- v.reserve(1000);
- t = 0;
- for (size_t i = 0; i < 1000; i++) {
- v.add((void *)(intptr_t)i);
- }
- for (size_t i = 0; i < 1000; i++) {
- t += (int)(intptr_t)v.v[i];
- }
- REQUIRE(t == 999 * 500);
-
- Intervals in;
- in.insert(1);
- REQUIRE(in.n == 2);
- in.insert(2);
- REQUIRE(in.n == 2);
- in.insert(6);
- REQUIRE(in.n == 4);
- in.insert(7);
- REQUIRE(in.n == 4);
- in.insert(9);
- REQUIRE(in.n == 6);
- in.insert(4);
- REQUIRE(in.n == 8);
- in.insert(5);
- REQUIRE(in.n == 6);
- in.insert(3);
- REQUIRE(in.n == 4);
- in.insert(8);
- REQUIRE(in.n == 2);
-
- UnionFind uf;
- uf.size(4);
- uf.unify(0, 1);
- uf.unify(2, 3);
- REQUIRE(uf.find(2) == uf.find(3));
- REQUIRE(uf.find(0) == uf.find(1));
- REQUIRE(uf.find(0) != uf.find(3));
- REQUIRE(uf.find(1) != uf.find(3));
- REQUIRE(uf.find(1) != uf.find(2));
- REQUIRE(uf.find(0) != uf.find(2));
- uf.unify(1, 2);
- REQUIRE(uf.find(0) == uf.find(3));
- REQUIRE(uf.find(1) == uf.find(3));
-}
-
-static bool
-compare(void *a, void *b)
-{
- return a < b;
-}
-
-TEST_CASE("test sort", "[libts][Vec]")
-{
- Vec<void *> v;
- for (long i = 1; i <= 1000; ++i) {
- v.add(reinterpret_cast<void *>(static_cast<intptr_t>(((i * 149) % 1000) +
1)));
- }
- v.qsort(&compare);
- int failures = 0;
- for (int i = 0; i < 1000; ++i) {
- if (reinterpret_cast<void *>(static_cast<intptr_t>(i + 1)) != v[i]) {
- failures++;
- }
- }
- REQUIRE(failures == 0);
-
- v.clear();
- for (long i = 1; i <= 1000000; ++i) {
- v.add(reinterpret_cast<void *>(static_cast<intptr_t>(((i * 51511) %
1000000) + 1)));
- }
- v.qsort(&compare);
- failures = 0;
- for (long i = 0; i < 1000000; ++i) {
- if (reinterpret_cast<void *>(static_cast<intptr_t>(i + 1)) != v[i]) {
- failures++;
- }
- }
- REQUIRE(failures == 0);
-
- v.clear();
- for (long i = 1; i <= 1000000; ++i) {
- // This should be every number 1..500000 twice.
- v.add(reinterpret_cast<void *>(static_cast<intptr_t>(((i * 199999) %
500000) + 1)));
- }
- v.qsort(&compare);
- failures = 0;
- for (long i = 0; i < 1000000; ++i) {
- if (reinterpret_cast<void *>(static_cast<intptr_t>((i / 2) + 1)) != v[i]) {
- failures++;
- }
- }
- REQUIRE(failures == 0);
-
- // Very long array, already sorted. This is what broke before.
- v.clear();
- for (long i = 1; i <= 10000000; ++i) {
- v.add(reinterpret_cast<void *>(static_cast<intptr_t>(i)));
- }
- v.qsort(&compare);
- failures = 0;
- for (long i = 0; i < 10000000; ++i) {
- if (reinterpret_cast<void *>(static_cast<intptr_t>(i + 1)) != v[i]) {
- failures++;
- }
- }
- REQUIRE(failures == 0);
-
- // very long, reverse sorted.
- v.clear();
- for (long i = 10000000; i >= 1; --i) {
- v.add(reinterpret_cast<void *>(static_cast<intptr_t>(i)));
- }
- v.qsort(&compare);
- failures = 0;
- for (long i = 0; i < 10000000; ++i) {
- if (reinterpret_cast<void *>(static_cast<intptr_t>(i + 1)) != v[i]) {
- failures++;
- }
- }
- REQUIRE(failures == 0);
-}