File: pooled_string.h

package info (click to toggle)
tilemaker 3.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 78,284 kB
  • sloc: cpp: 28,715; ansic: 4,052; makefile: 180; ruby: 77; sh: 6
file content (64 lines) | stat: -rw-r--r-- 2,263 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#ifndef _POOLED_STRING_H
#define _POOLED_STRING_H

// std::string is quite general:
// - mutable
// - unlimited length
// - capacity can differ from size
// - can deallocate its dynamic memory
//
// Our use case, by contrast is immutable, bounded strings that live for the
// duration of the process.
//
// This gives us some room to have less memory overhead, especially on
// g++, whose implementation of std::string requires 32 bytes.
//
// Thus, we implement `PooledString`. It has a size of 16 bytes, and a small
// string optimization for strings <= 15 bytes. (We will separately teach
// AttributePair to encode Latin-character strings more efficiently, so that many
// strings of size 24 or less fit in 15 bytes.)
//
// If it needs to allocate memory, it does so from a shared pool. It is unable
// to free the memory once allocated.

// PooledString has one of three modes:
// - [126:127] = 00: small-string, length is in [120:125], lower 15 bytes are string
// - [126:127] = 10: pooled string, table is in bytes 1..3, offset in bytes 4..5, length in bytes 6..7
// - [126:127] = 11: pointer to std::string, pointer is in bytes 8..15
//
// Note that the pointer mode is not safe to be stored. It exists just to allow
// lookups in the AttributePair map before deciding to allocate a string.

#include <cstdint>
#include <vector>
#include <string>
#include <protozero/data_view.hpp>

namespace PooledStringNS {
  class PooledString {
    public:
      // Create a short string or heap string, long-lived.
      PooledString(const std::string& str);


      // Wrap a protozero::data_view - only valid so long as the
      // data_view that is pointed to is valid; call ensureStringIsOwned
      // if you need to persist the string.
      PooledString(const protozero::data_view* str);
      size_t size() const;
      bool operator<(const PooledString& other) const;
      bool operator==(const PooledString& other) const;
      bool operator!=(const PooledString& other) const;
      std::string toString() const;
      const char* data() const;
      void ensureStringIsOwned();

    private:
      // 0..3 is index into table, 4..5 is offset, 6..7 is length
      uint8_t storage[16];
  };
}

using PooledString = PooledStringNS::PooledString;

#endif