@@ -79,212 +79,81 @@ void CollectionParent::check_level() const
7979 throw LogicError (ErrorCodes::LimitExceeded, " Max nesting level reached" );
8080 }
8181}
82- void CollectionParent::set_backlink (ColKey col_key, ObjLink new_link) const
83- {
84- if (new_link && new_link.get_obj_key ()) {
85- auto t = get_table ();
86- auto target_table = t->get_parent_group ()->get_table (new_link.get_table_key ());
87- ColKey backlink_col_key;
88- auto type = col_key.get_type ();
89- if (type == col_type_TypedLink || type == col_type_Mixed || col_key.is_dictionary ()) {
90- // This may modify the target table
91- backlink_col_key = target_table->find_or_add_backlink_column (col_key, t->get_key ());
92- // it is possible that this was a link to the same table and that adding a backlink column has
93- // caused the need to update this object as well.
94- update_if_needed ();
95- }
96- else {
97- backlink_col_key = t->get_opposite_column (col_key);
98- }
99- auto obj_key = new_link.get_obj_key ();
100- auto target_obj = obj_key.is_unresolved () ? target_table->try_get_tombstone (obj_key)
101- : target_table->try_get_object (obj_key);
102- if (!target_obj) {
103- throw InvalidArgument (ErrorCodes::KeyNotFound, " Target object not found" );
104- }
105- target_obj.add_backlink (backlink_col_key, get_object ().get_key ());
106- }
107- }
10882
109- bool CollectionParent::replace_backlink (ColKey col_key, ObjLink old_link, ObjLink new_link, CascadeState& state) const
83+ template <typename Base, template <typename > typename Collection, typename LinkCol>
84+ std::unique_ptr<Base> create_collection (ColKey col_key, size_t level)
11085{
111- bool recurse = remove_backlink (col_key, old_link, state);
112- set_backlink (col_key, new_link);
113-
114- return recurse;
115- }
116-
117- bool CollectionParent::remove_backlink (ColKey col_key, ObjLink old_link, CascadeState& state) const
118- {
119- if (old_link && old_link.get_obj_key ()) {
120- auto t = get_table ();
121- REALM_ASSERT (t->valid_column (col_key));
122- ObjKey old_key = old_link.get_obj_key ();
123- auto target_obj = t->get_parent_group ()->get_object (old_link);
124- TableRef target_table = target_obj.get_table ();
125- ColKey backlink_col_key;
126- auto type = col_key.get_type ();
127- if (type == col_type_TypedLink || type == col_type_Mixed || col_key.is_dictionary ()) {
128- backlink_col_key = target_table->find_or_add_backlink_column (col_key, t->get_key ());
129- }
130- else {
131- backlink_col_key = t->get_opposite_column (col_key);
132- }
133-
134- bool strong_links = target_table->is_embedded ();
135- bool is_unres = old_key.is_unresolved ();
136-
137- bool last_removed = target_obj.remove_one_backlink (backlink_col_key, get_object ().get_key ()); // Throws
138- if (is_unres) {
139- if (last_removed) {
140- // Check is there are more backlinks
141- if (!target_obj.has_backlinks (false )) {
142- // Tombstones can be erased right away - there is no cascading effect
143- target_table->m_tombstones ->erase (old_key, state);
144- }
145- }
146- }
147- else {
148- return state.enqueue_for_cascade (target_obj, strong_links, last_removed);
149- }
150- }
151-
152- return false ;
153- }
154-
155- LstBasePtr CollectionParent::get_listbase_ptr (ColKey col_key) const
156- {
157- auto table = get_table ();
158- auto attr = table->get_column_attr (col_key);
159- REALM_ASSERT (attr.test (col_attr_List) || attr.test (col_attr_Nullable));
160- bool nullable = attr.test (col_attr_Nullable);
161-
162- switch (table->get_column_type (col_key)) {
163- case type_Int: {
86+ bool nullable = col_key.get_attrs ().test (col_attr_Nullable);
87+ switch (col_key.get_type ()) {
88+ case col_type_Int:
16489 if (nullable)
165- return std::make_unique<Lst<util::Optional<Int>>>(col_key);
166- else
167- return std::make_unique<Lst<Int>>(col_key);
168- }
169- case type_Bool: {
90+ return std::make_unique<Collection<util::Optional<Int>>>(col_key);
91+ return std::make_unique<Collection<Int>>(col_key);
92+ case col_type_Bool:
17093 if (nullable)
171- return std::make_unique<Lst<util::Optional<Bool>>>(col_key);
172- else
173- return std::make_unique<Lst<Bool>>(col_key);
174- }
175- case type_Float: {
94+ return std::make_unique<Collection<util::Optional<Bool>>>(col_key);
95+ return std::make_unique<Collection<Bool>>(col_key);
96+ case col_type_Float:
17697 if (nullable)
177- return std::make_unique<Lst<util::Optional<Float>>>(col_key);
178- else
179- return std::make_unique<Lst<Float>>(col_key);
180- }
181- case type_Double: {
98+ return std::make_unique<Collection<util::Optional<Float>>>(col_key);
99+ return std::make_unique<Collection<Float>>(col_key);
100+ case col_type_Double:
182101 if (nullable)
183- return std::make_unique<Lst<util::Optional<Double>>>(col_key);
184- else
185- return std::make_unique<Lst<Double>>(col_key);
186- }
187- case type_String: {
188- return std::make_unique<Lst<String>>(col_key);
189- }
190- case type_Binary: {
191- return std::make_unique<Lst<Binary>>(col_key);
192- }
193- case type_Timestamp: {
194- return std::make_unique<Lst<Timestamp>>(col_key);
195- }
196- case type_Decimal: {
197- return std::make_unique<Lst<Decimal128>>(col_key);
198- }
199- case type_ObjectId: {
102+ return std::make_unique<Collection<util::Optional<Double>>>(col_key);
103+ return std::make_unique<Collection<Double>>(col_key);
104+ case col_type_String:
105+ return std::make_unique<Collection<String>>(col_key);
106+ case col_type_Binary:
107+ return std::make_unique<Collection<Binary>>(col_key);
108+ case col_type_Timestamp:
109+ return std::make_unique<Collection<Timestamp>>(col_key);
110+ case col_type_Decimal:
111+ return std::make_unique<Collection<Decimal128>>(col_key);
112+ case col_type_ObjectId:
200113 if (nullable)
201- return std::make_unique<Lst<util::Optional<ObjectId>>>(col_key);
202- else
203- return std::make_unique<Lst<ObjectId>>(col_key);
204- }
205- case type_UUID: {
114+ return std::make_unique<Collection<util::Optional<ObjectId>>>(col_key);
115+ return std::make_unique<Collection<ObjectId>>(col_key);
116+ case col_type_UUID:
206117 if (nullable)
207- return std::make_unique<Lst<util::Optional<UUID>>>(col_key);
208- else
209- return std::make_unique<Lst<UUID>>(col_key);
210- }
211- case type_TypedLink: {
212- return std::make_unique<Lst<ObjLink>>(col_key);
213- }
214- case type_Mixed: {
215- return std::make_unique<Lst<Mixed>>(col_key, get_level () + 1 );
216- }
217- case type_Link:
218- return std::make_unique<LnkLst>(col_key);
118+ return std::make_unique<Collection<util::Optional<UUID>>>(col_key);
119+ return std::make_unique<Collection<UUID>>(col_key);
120+ case col_type_TypedLink:
121+ return std::make_unique<Collection<ObjLink>>(col_key);
122+ case col_type_Mixed:
123+ return std::make_unique<Collection<Mixed>>(col_key, level + 1 );
124+ case col_type_Link:
125+ return std::make_unique<LinkCol>(col_key);
126+ default :
127+ REALM_TERMINATE (" Unsupported column type." );
219128 }
220- REALM_TERMINATE (" Unsupported column type" );
221129}
222130
223- SetBasePtr CollectionParent::get_setbase_ptr (ColKey col_key) const
131+ LstBasePtr CollectionParent::get_listbase_ptr (ColKey col_key, size_t level)
224132{
225- auto table = get_table ();
226- auto attr = table->get_column_attr (col_key);
227- REALM_ASSERT (attr.test (col_attr_Set));
228- bool nullable = attr.test (col_attr_Nullable);
133+ REALM_ASSERT (col_key.get_attrs ().test (col_attr_List) || col_key.get_type () == col_type_Mixed);
134+ return create_collection<LstBase, Lst, LnkLst>(col_key, level);
135+ }
229136
230- switch (table->get_column_type (col_key)) {
231- case type_Int:
232- if (nullable)
233- return std::make_unique<Set<util::Optional<Int>>>(col_key);
234- return std::make_unique<Set<Int>>(col_key);
235- case type_Bool:
236- if (nullable)
237- return std::make_unique<Set<util::Optional<Bool>>>(col_key);
238- return std::make_unique<Set<Bool>>(col_key);
239- case type_Float:
240- if (nullable)
241- return std::make_unique<Set<util::Optional<Float>>>(col_key);
242- return std::make_unique<Set<Float>>(col_key);
243- case type_Double:
244- if (nullable)
245- return std::make_unique<Set<util::Optional<Double>>>(col_key);
246- return std::make_unique<Set<Double>>(col_key);
247- case type_String:
248- return std::make_unique<Set<String>>(col_key);
249- case type_Binary:
250- return std::make_unique<Set<Binary>>(col_key);
251- case type_Timestamp:
252- return std::make_unique<Set<Timestamp>>(col_key);
253- case type_Decimal:
254- return std::make_unique<Set<Decimal128>>(col_key);
255- case type_ObjectId:
256- if (nullable)
257- return std::make_unique<Set<util::Optional<ObjectId>>>(col_key);
258- return std::make_unique<Set<ObjectId>>(col_key);
259- case type_UUID:
260- if (nullable)
261- return std::make_unique<Set<util::Optional<UUID>>>(col_key);
262- return std::make_unique<Set<UUID>>(col_key);
263- case type_TypedLink:
264- return std::make_unique<Set<ObjLink>>(col_key);
265- case type_Mixed:
266- return std::make_unique<Set<Mixed>>(col_key);
267- case type_Link:
268- return std::make_unique<LnkSet>(col_key);
269- }
270- REALM_TERMINATE (" Unsupported column type." );
137+ SetBasePtr CollectionParent::get_setbase_ptr (ColKey col_key, size_t level)
138+ {
139+ REALM_ASSERT (col_key.get_attrs ().test (col_attr_Set));
140+ return create_collection<SetBase, Set, LnkSet>(col_key, level);
271141}
272142
273- CollectionBasePtr CollectionParent::get_collection_ptr (ColKey col_key) const
143+ CollectionBasePtr CollectionParent::get_collection_ptr (ColKey col_key, size_t level)
274144{
275145 if (col_key.is_list ()) {
276- return get_listbase_ptr (col_key);
146+ return get_listbase_ptr (col_key, level );
277147 }
278148 else if (col_key.is_set ()) {
279- return get_setbase_ptr (col_key);
149+ return get_setbase_ptr (col_key, level );
280150 }
281151 else if (col_key.is_dictionary ()) {
282- return std::make_unique<Dictionary>(col_key, get_level () + 1 );
152+ return std::make_unique<Dictionary>(col_key, level + 1 );
283153 }
284154 return {};
285155}
286156
287-
288157int64_t CollectionParent::generate_key (size_t sz)
289158{
290159 static std::mt19937 gen32;
@@ -307,5 +176,13 @@ int64_t CollectionParent::generate_key(size_t sz)
307176 return key;
308177}
309178
179+ void CollectionParent::set_key (BPlusTreeMixed& tree, size_t index)
180+ {
181+ int64_t key = generate_key (tree.size ());
182+ while (tree.find_key (key) != realm::not_found) {
183+ key++;
184+ }
185+ tree.set_key (index, key);
186+ }
310187
311188} // namespace realm
0 commit comments