small-cache 0.0.1__tar.gz → 0.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,9 +14,9 @@ jobs:
14
14
  python-version: ["3.11", "3.12"]
15
15
 
16
16
  steps:
17
- - uses: actions/checkout@v4
17
+ - uses: actions/checkout@v5
18
18
 
19
- - uses: actions/setup-python@v5
19
+ - uses: actions/setup-python@v6
20
20
  with:
21
21
  python-version: ${{ matrix.python-version }}
22
22
 
@@ -11,7 +11,7 @@ jobs:
11
11
  name: Build SDist
12
12
  runs-on: ubuntu-latest
13
13
  steps:
14
- - uses: actions/checkout@v4
14
+ - uses: actions/checkout@v5
15
15
  with:
16
16
  submodules: true
17
17
 
@@ -21,7 +21,7 @@ jobs:
21
21
  - name: Check metadata
22
22
  run: pipx run twine check dist/*
23
23
 
24
- - uses: actions/upload-artifact@v4
24
+ - uses: actions/upload-artifact@v5
25
25
  with:
26
26
  name: dist-sdist
27
27
  path: dist/*.tar.gz
@@ -36,18 +36,18 @@ jobs:
36
36
  os: [ubuntu-latest, macos-latest, windows-latest]
37
37
 
38
38
  steps:
39
- - uses: actions/checkout@v4
39
+ - uses: actions/checkout@v5
40
40
  with:
41
41
  submodules: true
42
42
 
43
- - uses: pypa/cibuildwheel@v3.0
43
+ - uses: pypa/cibuildwheel@v3.2
44
44
 
45
45
  - name: Verify clean directory
46
46
  run: git diff --exit-code
47
47
  shell: bash
48
48
 
49
49
  - name: Upload wheels
50
- uses: actions/upload-artifact@v4
50
+ uses: actions/upload-artifact@v5
51
51
  with:
52
52
  path: wheelhouse/*.whl
53
53
  name: dist-${{ matrix.os }}
@@ -59,8 +59,8 @@ jobs:
59
59
  if: github.event_name == 'release' && github.event.action == 'published'
60
60
 
61
61
  steps:
62
- - uses: actions/setup-python@v5
63
- - uses: actions/download-artifact@v4
62
+ - uses: actions/setup-python@v6
63
+ - uses: actions/download-artifact@v6
64
64
  with:
65
65
  path: dist
66
66
  pattern: dist-*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: small-cache
3
- Version: 0.0.1
3
+ Version: 0.0.2
4
4
  Summary: Small cache
5
5
  Author: kam1k4dze
6
6
  Classifier: License :: OSI Approved :: BSD License
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "small-cache"
7
- version = "0.0.1"
7
+ version = "0.0.2"
8
8
  description = "Small cache"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -55,7 +55,7 @@ class SmallCache {
55
55
  using str = std::string;
56
56
  using strVec = std::vector<str>;
57
57
  using fwStr = boost::flyweight<str>;
58
- using strVecUPtr = std::unique_ptr<std::vector<fwStr> >;
58
+ using strVecUPtr = std::unique_ptr<std::vector<fwStr>>;
59
59
 
60
60
  using AttributeValue = std::variant<std::monostate, double, bool, fwStr, strVecUPtr>;
61
61
  using pyAttrValue = std::variant<std::monostate, bool, double, str, strVec>;
@@ -109,7 +109,7 @@ public:
109
109
  return (attrs_flags[w] >> b) & 1u;
110
110
  }
111
111
 
112
- [[nodiscard]] std::optional<std::reference_wrapper<AttributeValue> > getValue(size_t idx) noexcept {
112
+ [[nodiscard]] std::optional<std::reference_wrapper<AttributeValue>> getValue(size_t idx) noexcept {
113
113
  if (!hasIdx(idx))
114
114
  return std::nullopt;
115
115
 
@@ -130,7 +130,7 @@ public:
130
130
  return value.size() > pos ? std::optional{std::ref(value[pos])} : std::nullopt; // just-in-case
131
131
  }
132
132
 
133
- [[nodiscard]] std::optional<std::reference_wrapper<const AttributeValue> > getValue(size_t idx) const noexcept {
133
+ [[nodiscard]] std::optional<std::reference_wrapper<const AttributeValue>> getValue(size_t idx) const noexcept {
134
134
  if (auto ref = const_cast<MarkedItem *>(this)->getValue(idx))
135
135
  return std::cref(ref->get());
136
136
  return std::nullopt;
@@ -142,7 +142,7 @@ public:
142
142
  item.attrs_flags.fill(0);
143
143
 
144
144
  // build a slot for each possible attr index
145
- std::vector<std::optional<AttributeValue> > slots(attrMap.size());
145
+ std::vector<std::optional<AttributeValue>> slots(attrMap.size());
146
146
 
147
147
  // 1) collect into slots[] by index
148
148
  for (auto &[name, pyVal]: attrs) {
@@ -185,29 +185,29 @@ public:
185
185
 
186
186
  static AttributeValue convert_value(const json::AttributeValue &src) {
187
187
  return std::visit(overloaded{
188
- [](bool b) -> AttributeValue { return b; },
189
- [](double d) -> AttributeValue { return d; },
190
- [](const str &s) -> AttributeValue {
191
- // if (s.empty()) return std::monostate{};
192
- return fwStr{s};
193
- },
194
-
195
- [](const std::vector<glz::raw_json> &json_vec) -> AttributeValue {
196
- auto out = std::make_unique<std::vector<fwStr> >();
197
- out->reserve(json_vec.size());
198
- for (auto &r: json_vec)
199
- if (!r.str.empty())
200
- out->emplace_back(r.str);
201
- // if (out->empty()) {
202
- // return std::monostate{};
203
- // }
204
- out->shrink_to_fit();
205
- return out;
206
- },
207
- [](const std::optional<glz::raw_json> &o) -> AttributeValue {
208
- // if (!o.has_value() || o->str.empty()) return std::monostate{};
209
- return fwStr{o->str};
210
- },
188
+ [](bool b) -> AttributeValue { return b; },
189
+ [](double d) -> AttributeValue { return d; },
190
+ [](const str &s) -> AttributeValue {
191
+ // if (s.empty()) return std::monostate{};
192
+ return fwStr{s};
193
+ },
194
+
195
+ [](const std::vector<glz::raw_json> &json_vec) -> AttributeValue {
196
+ auto out = std::make_unique<std::vector<fwStr>>();
197
+ out->reserve(json_vec.size());
198
+ for (auto &r: json_vec)
199
+ if (!r.str.empty())
200
+ out->emplace_back(r.str);
201
+ // if (out->empty()) {
202
+ // return std::monostate{};
203
+ // }
204
+ out->shrink_to_fit();
205
+ return out;
206
+ },
207
+ [](const std::optional<glz::raw_json> &o) -> AttributeValue {
208
+ // if (!o.has_value() || o->str.empty()) return std::monostate{};
209
+ return fwStr{o->str};
210
+ },
211
211
 
212
212
  },
213
213
  src);
@@ -216,17 +216,17 @@ public:
216
216
 
217
217
  static pyAttrValue convert_valueJ(const json::AttributeValue &src) {
218
218
  return std::visit(overloaded{
219
- [](std::monostate b) -> pyAttrValue { return b; },
220
- [](bool b) -> pyAttrValue { return b; },
221
- [](double d) -> pyAttrValue { return d; },
222
- [](const str &s) -> pyAttrValue { return s; },
223
- [](const std::vector<glz::raw_json> &json_vec) -> pyAttrValue {
224
- return json_vec | std::views::transform([](const glz::raw_json &j) -> str {
225
- return j.str;
226
- }) |
227
- std::ranges::to<strVec>();
228
- },
229
- [](const std::optional<glz::raw_json> &o) -> pyAttrValue { return o ? o->str : ""; },
219
+ [](std::monostate b) -> pyAttrValue { return b; },
220
+ [](bool b) -> pyAttrValue { return b; },
221
+ [](double d) -> pyAttrValue { return d; },
222
+ [](const str &s) -> pyAttrValue { return s; },
223
+ [](const std::vector<glz::raw_json> &json_vec) -> pyAttrValue {
224
+ return json_vec | std::views::transform([](const glz::raw_json &j) -> str {
225
+ return j.str;
226
+ }) |
227
+ std::ranges::to<strVec>();
228
+ },
229
+ [](const std::optional<glz::raw_json> &o) -> pyAttrValue { return o ? o->str : ""; },
230
230
 
231
231
  },
232
232
  src);
@@ -234,54 +234,54 @@ public:
234
234
 
235
235
  static pyAttrValue convert_value(const AttributeValue &src) {
236
236
  return std::visit(overloaded{
237
- [](std::monostate b) -> pyAttrValue { return b; },
238
- [](bool b) -> pyAttrValue { return b; },
239
- [](double d) -> pyAttrValue { return d; },
240
- [](const fwStr &s) -> pyAttrValue { return s; },
241
- [](const strVecUPtr &fw_vec) -> pyAttrValue {
242
- return *fw_vec | std::views::transform([](const fwStr &s) -> str { return s; }) |
243
- std::ranges::to<strVec>();
244
- },
237
+ [](std::monostate b) -> pyAttrValue { return b; },
238
+ [](bool b) -> pyAttrValue { return b; },
239
+ [](double d) -> pyAttrValue { return d; },
240
+ [](const fwStr &s) -> pyAttrValue { return s; },
241
+ [](const strVecUPtr &fw_vec) -> pyAttrValue {
242
+ return *fw_vec | std::views::transform([](const fwStr &s) -> str { return s; }) |
243
+ std::ranges::to<strVec>();
244
+ },
245
245
  },
246
246
  src);
247
247
  }
248
248
 
249
249
  static AttributeValue convert_value(const pyAttrValue &src) {
250
250
  return std::visit(overloaded{
251
- [](std::monostate b) -> AttributeValue { return b; },
252
- [](bool b) -> AttributeValue { return b; },
253
- [](double d) -> AttributeValue { return d; },
254
- [](const str &s) -> AttributeValue { return fwStr{s}; },
255
- [](const strVec &vec) -> AttributeValue {
256
- auto out = std::make_unique<std::vector<fwStr> >();
257
- out->reserve(vec.size());
258
- for (auto &r: vec) {
259
- out->emplace_back(r);
260
- }
261
- out->shrink_to_fit();
262
- return out;
263
- },
251
+ [](std::monostate b) -> AttributeValue { return b; },
252
+ [](bool b) -> AttributeValue { return b; },
253
+ [](double d) -> AttributeValue { return d; },
254
+ [](const str &s) -> AttributeValue { return fwStr{s}; },
255
+ [](const strVec &vec) -> AttributeValue {
256
+ auto out = std::make_unique<std::vector<fwStr>>();
257
+ out->reserve(vec.size());
258
+ for (auto &r: vec) {
259
+ out->emplace_back(r);
260
+ }
261
+ out->shrink_to_fit();
262
+ return out;
263
+ },
264
264
  },
265
265
  src);
266
266
  }
267
267
 
268
268
  static str to_string(const pyAttrValue &src) {
269
269
  return std::visit(overloaded{
270
- [](std::monostate) -> str { return "null"; },
271
- [](bool b) -> str { return b ? "true" : "false"; },
272
- [](double d) -> str { return std::to_string(d); },
273
- [](const str &s) -> str { return s; },
274
-
275
- [](const strVec &vecptr) -> str {
276
- str out = "[";
277
-
278
- for (auto &r: vecptr) {
279
- out.append(r);
280
- out.append(",");
281
- }
282
- out.append("]");
283
- return out;
284
- },
270
+ [](std::monostate) -> str { return "null"; },
271
+ [](bool b) -> str { return b ? "true" : "false"; },
272
+ [](double d) -> str { return std::to_string(d); },
273
+ [](const str &s) -> str { return s; },
274
+
275
+ [](const strVec &vecptr) -> str {
276
+ str out = "[";
277
+
278
+ for (auto &r: vecptr) {
279
+ out.append(r);
280
+ out.append(",");
281
+ }
282
+ out.append("]");
283
+ return out;
284
+ },
285
285
  },
286
286
  src);
287
287
  }
@@ -311,7 +311,7 @@ public:
311
311
  return {};
312
312
  return convert_value(*attr_value);
313
313
  }) |
314
- std::ranges::to<std::vector<pyAttrValue> >();
314
+ std::ranges::to<std::vector<pyAttrValue>>();
315
315
  }
316
316
  return {};
317
317
  }
@@ -320,11 +320,11 @@ public:
320
320
  struct getAllResponse {
321
321
  uint64_t iterator_version{};
322
322
  uint64_t iterator{};
323
- std::vector<std::pair<str, std::vector<pyAttrValue> > > result{};
323
+ std::vector<std::pair<str, std::vector<pyAttrValue>>> result{};
324
324
  };
325
325
 
326
326
  str get_all(const strVec &attributes, uint64_t per_iteration = 10000, uint64_t iterator_version = 0,
327
- uint64_t iterator = 0) {
327
+ uint64_t iterator = 0) {
328
328
  if (transactionOpened)
329
329
  throw std::runtime_error("Can't get all when transaction is opened");
330
330
  if (iterator && iterator_version == 0) {
@@ -354,7 +354,7 @@ public:
354
354
  }
355
355
 
356
356
 
357
- void begin_transaction(uint64_t estimated_number_of_items = 0) {
357
+ void begin_transaction(uint64_t estimated_number_of_items = 0, bool remove_old_items = true) {
358
358
  if (transactionOpened) {
359
359
  throw std::runtime_error("Transaction already open");
360
360
  }
@@ -364,6 +364,7 @@ public:
364
364
  }
365
365
  oldCacheSize = cache.size();
366
366
  transactionOpened = true;
367
+ transactionShouldRemoveOldItems = remove_old_items;
367
368
  }
368
369
 
369
370
  void end_transaction() {
@@ -375,11 +376,17 @@ public:
375
376
  it.value().isNew = false;
376
377
  ++it;
377
378
  } else {
378
- it = cache.erase(it);
379
+ if (transactionShouldRemoveOldItems) {
380
+ it = cache.erase(it);
381
+ }
382
+ else {
383
+ ++it;
384
+ }
379
385
  }
380
386
  }
381
387
  increaseIteratorVersion();
382
388
  transactionOpened = false;
389
+ transactionShouldRemoveOldItems = true;
383
390
  }
384
391
 
385
392
  size_t load_page(const str &json_text) {
@@ -408,11 +415,12 @@ public:
408
415
  }
409
416
 
410
417
  tsl::sparse_map<str, MarkedItem> cache;
411
- absl::flat_hash_map<str, uint8_t, absl::Hash<str> > attrMap;
418
+ absl::flat_hash_map<str, uint8_t, absl::Hash<str>> attrMap;
412
419
  strVec attrIdx;
413
420
  const uint8_t numberOfAttributes;
414
421
  size_t oldCacheSize = 0;
415
422
  bool transactionOpened = false;
423
+ bool transactionShouldRemoveOldItems = true;
416
424
  uint64_t iterator_version = 1; // for get_all()
417
425
  };
418
426
 
@@ -421,7 +429,9 @@ NB_MODULE(_small_cache_impl, m) {
421
429
  nb::class_<SmallCache> cache(m, "SmallCache");
422
430
  cache
423
431
  .def(nb::init<std::vector<std::string> >(), nb::arg("attribute_names"))
424
- .def("begin_transaction", &SmallCache::begin_transaction, nb::arg("estimated_number_of_items") = 0)
432
+ .def("begin_transaction", &SmallCache::begin_transaction,
433
+ nb::arg("estimated_number_of_items") = 0,
434
+ nb::arg("remove_old_items") = true)
425
435
  .def("end_transaction", &SmallCache::end_transaction)
426
436
  .def("add", &SmallCache::add_item, nb::arg("item_id"), nb::arg("attributes"))
427
437
  .def("get", &SmallCache::get, nb::arg("id"), nb::arg("attributes"))
File without changes
File without changes
File without changes