void free_key_node(PanDB * const db, KeyNode * const key_node) { if (key_node == NULL) { return; } assert(key_node->slot == NULL); release_key(key_node->key); key_node->key = NULL; free_slip_map(&key_node->properties); key_node->properties = NULL; HttpHandlerContext * context = db->context; if (key_node->expirable != NULL) { remove_expirable_from_tree(db, key_node->expirable); remove_entry_from_slab(&context->expirables_slab, key_node->expirable); key_node->expirable = NULL; } free(key_node); }
int handle_op_records_put(RecordsPutOp * const put_op, HttpHandlerContext * const context) { yajl_gen json_gen; PanDB *pan_db; if (get_pan_db_by_layer_name(context, put_op->layer_name->val, AUTOMATICALLY_CREATE_LAYERS, &pan_db) < 0) { release_key(put_op->layer_name); release_key(put_op->key); free_slip_map(&put_op->properties); free_slip_map(&put_op->special_properties); return HTTP_NOTFOUND; } release_key(put_op->layer_name); int status; KeyNode *key_node; status = get_key_node_from_key(pan_db, put_op->key, 1, &key_node); release_key(put_op->key); if (key_node == NULL) { assert(status <= 0); free_slip_map(&put_op->properties); free_slip_map(&put_op->special_properties); return HTTP_NOTFOUND; } assert(status > 0); const Rectangle2D * const qbounds = &pan_db->qbounds; if (put_op->position_set != 0 && !(put_op->position.latitude >= qbounds->edge0.latitude && put_op->position.longitude >= qbounds->edge0.longitude && put_op->position.latitude < qbounds->edge1.latitude && put_op->position.longitude < qbounds->edge1.longitude)) { put_op->position_set = 0; } if (status > 0 && put_op->position_set != 0 && key_node->slot != NULL) { #if PROJECTION const Position2D * const previous_position = &key_node->slot->real_position; #else const Position2D * const previous_position = &key_node->slot->position; #endif if (previous_position->latitude == put_op->position.latitude && previous_position->longitude == put_op->position.longitude) { put_op->position_set = 0; } else { remove_entry_from_key_node(pan_db, key_node, 0); assert(key_node->slot != NULL); key_node->slot = NULL; } } if (put_op->position_set != 0) { Slot slot; Slot *new_slot; init_slot(&slot); slot = (Slot) { #if PROJECTION .real_position = put_op->position, #endif .position = put_op->position, .key_node = key_node }; if (add_slot(pan_db, &slot, &new_slot) != 0) { RB_REMOVE(KeyNodes_, &pan_db->key_nodes, key_node); key_node->slot = NULL; free_key_node(pan_db, key_node); free_slip_map(&put_op->properties); free_slip_map(&put_op->special_properties); return HTTP_SERVUNAVAIL; } key_node->slot = new_slot; assert(new_slot != NULL); } if (put_op->special_properties != NULL) { RecordsPutApplySpecialPropertiesCBContext cb_context = { .target_map_pnt = &key_node->properties }; slip_map_foreach(&put_op->special_properties, records_put_apply_special_properties_cb, &cb_context); free_slip_map(&put_op->special_properties); } if (key_node->properties == NULL) { key_node->properties = put_op->properties; } else { RecordsPutMergePropertiesCBContext cb_context = { .target_map_pnt = &key_node->properties }; slip_map_foreach(&put_op->properties, records_put_merge_properties_cb, &cb_context); free_slip_map(&put_op->properties); } Expirable *expirable = key_node->expirable; if (put_op->expires_at != (time_t) 0) { if (expirable == NULL) { Expirable new_expirable = { .ts = put_op->expires_at, .key_node = key_node }; expirable = add_entry_to_slab(&context->expirables_slab, &new_expirable); key_node->expirable = expirable; add_expirable_to_tree(pan_db, expirable); } else { if (expirable->ts != put_op->expires_at) { remove_expirable_from_tree(pan_db, expirable); expirable->ts = put_op->expires_at; add_expirable_to_tree(pan_db, expirable); } } assert(expirable->key_node == key_node); } else if (expirable != NULL) {