Hello, and I have this problem again. I need to make my container look like a map, but storing only the key in memory, and value writing to a file whose name is the key.

With mymap[999] = 100; 999 goes to the AVL tree, and then a file is created with the name 999, and the value 100 is stored in it.

the problem is what I need in order to be able to do this:

I cannot change anything in the modify method.

  void modify(int& a) {// базовый метод a += 5; } //Желаемый функционал myMap[2] = 20; int c = 30; myMap[3] = с; modify(myMap[2]); //меняет значение myMap[2] int a = myMap[1]; int b = myMap[2]; assert(b == 25);//проверяем изменилось ли myMap[2] = myMap[2] + 20;//снова меняем значение 

With modify(myMap[2]); , the value in myMap[2] should also change, and therefore in the file.

I understand that for mymap[999] = 100; need a proxy class returned by the container. But for modify(myMap[2]); and myMap[2] = myMap[2] + 20; proxy does not fit. It is possible that all proxies of the same key can have shared memory, but I do not know how.

The container itself now looks like this:

 template <typename Key, typename FileType, class Compare = std::less<Key>> class PersistentMap { public: typedef int size_type; typedef std::pair<Key, FileType> value_type; typedef FileType mapped_type; typedef AVL_Tree<Key, FileType> tree; private: std::string dirName; tree *strom; Compare comp; public: typedef typename tree::iterator iterator; typedef typename tree::const_iterator const_iterator; PersistentMap(std::string ag); const mapped_type operator[] (Key key); std::pair<iterator, bool> insert(const value_type& a); //... } 

I will be glad to advice how to implement it (perhaps an example).

A very long time I can not solve this problem.

UPD can create a stack in which there will be values, and after destroying the last instance of the proxy of this key, save the value? (I hope clearly explained the problem)

UPD_2

I know that at the moment the code is terribly structured, and where it is not logical. PersistentMap.hpp consists of PersistenMap+AVL_Tree I just divided them into 2 examples, because Avl right now does not matter, as they are in lib namespace.

PersistentMap

AVL_Tree

Main.cpp

At the moment I have with modify(myMap[2]); the value in myMap[2] increases, but with myMap[2] = myMap[2] + 20; the problem is, since the left object of the destructor collapses before the right, and is overwritten.

PS

Proxy related tasks:

You can return an instance of the proxy class that takes care of saving / loading the correct values.

  1. Импimplement implicit conversion operators

  2. Импinput the constructors, assignment operators

  3. The solution will be correct if multiple proxies share a common data store.

  • I have already told you that without changing the modify method, your task has no solution. - ixSci
  • and if you have a stack in which the value of the current proxies will be located. and only after the destruction of the last proxy to save the value in the file? Is this option possible? And if so, how to implement it? - Demolver
  • In the proxy destructor, you can write to the file, but this is, firstly, a dirty crutch, and secondly, it is very unreliable. You, most likely, just misunderstood the task. The teacher could not give you such a task if he himself understands at least something in C ++. - ixSci
  • Updated the post, making specifics and code examples, even if figs. - Demolver

1 answer 1

I am not ready to give a complete answer, because there is no minimally compiled example, but the following statement is not entirely correct:

But for modify(myMap[2]); and myMap[2] = myMap[2] + 20; proxy does not fit.

Here's a proxy for you, which is quite able to emulate a stored type in at least the three scenarios listed above:

 template<typename T> struct ValueProxy { ValueProxy(T& v) : value(v) { } operator T&() { return value; } operator const T&() const { return value; } ValueProxy& operator=(const T& nv) { value = nv; return *this; } T& value; }; 

Example of use:

 template<typename Key, typename Value> struct SomeMap { // Helpers using parent_t = std::map<Key, Value>; parent_t holder; // Part of interest ValueProxy<Value> operator[](const Key& key) { return {holder[key]}; } }; 

But the checks: http://ideone.com/DBTILc - here you can see that the modify() call succeeds, exactly like mymap[2] = mymap[2] + 100;

Everything else, I think, is a matter of technology. Well, or publish a compiled example of your map.

  • Read the question more carefully, after the execution of the modify function, the author wants the value to be updated not only in the tree, which is not a problem, but also in the file on which this tree was built. - ixSci
  • @ixSci It hurt. And how to solve is the business of the author. At a minimum, cache the original value and compare it with the current one in the destructor of the proxy - if it has changed, write to the file. Yes, you can lose intermediate results if the proxy object is long-lived. The second option - when creating a proxy, open a file, make it mmap() or CreateFileMapping (or find some cross-platform library that abstracts from the platform) and, accordingly, play with the display - there is a memory address, which means there will be no differences from a simple variable. - Monah Tuk
  • All this does not fit and the task here is not just to write a proxy, but to work to write to the file. mmap and other system API has no relation to C ++, and the author, as I understand it, the task lies precisely in the field of C ++ - this is a learning task. With the destructor version of the oblique and poor, but perhaps with some reservations it can be applied here. But then he should be your answer, because in its current form, it (the answer) does not answer the question of the author at all. - ixSci
  • @ixSci, the author did not give a minimal compilable implementation, in which it would be possible to make any changes, and there is no particular desire to write the asbtraction layer itself - there is no particular desire. Publish - add. To answer only within the framework of the educational task, and not possible solutions in general, is also a strange restriction for this resource, especially since it was not specifically imposed after such restrictions. - Monah Tuk
  • I updated the post, added code samples, terribly structured, but hopefully understandable. The goal was to write PersistentMap.hpp which will work with main.cpp - Demolver