2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-23 02:17:42 +00:00
ovs/lib/ovsdb-map-op.h

54 lines
1.7 KiB
C
Raw Normal View History

ovsdb-idl: Add partial map updates functionality. In the current implementation, every time an element of either a map or set column has to be modified, the entire content of the column is sent to the server to be updated. This is not a major problem if the information contained in the column for the corresponding row is small, but there are cases where these columns can have a significant amount of elements per row, or these values are updated frequently, therefore the cost of the modifications becomes high in terms of time and bandwidth. In this solution, the ovsdb-idl code is modified to use the RFC 7047 'mutate' operation, to allow sending partial modifications on map columns to the server. The functionality is exposed to clients in the vswitch idl. This was implemented through map operations. A map operation is defined as an insertion, update or deletion of a key-value pair inside a map. The idea is to minimize the amount of map operations that are send to the OVSDB server when a transaction is committed. In order to keep track of the requested map operations, structs map_op and map_op_list were defined with accompanying functions to manipulate them. These functions make sure that only one operation is send to the server for each key-value that wants to be modified, so multiple operation on a key value are collapsed into a single operation. As an example, if a client using the IDL updates several times the value for the same key, the functions will ensure that only the last value is send to the server, instead of multiple updates. Or, if the client inserts a key-value, and later on deletes the key before committing the transaction, then both actions cancel out and no map operation is send for that key. To keep track of the desired map operations on each transaction, a list of map operations (struct map_op_list) is created for every column on the row on which a map operation is performed. When a new map operation is requested on the same column, the corresponding map_op_list is checked to verify if a previous operations was performed on the same key, on the same transaction. If there is no previous operation, then the new operation is just added into the list. But if there was a previous operation on the same key, then the previous operation is collapsed with the new operation into a single operation that preserves the final result if both operations were to be performed sequentially. This design keep a small memory footprint during transactions. When a transaction is committed, the map operations lists are checked and all map operations that belong to the same map are grouped together into a single JSON RPC "mutate" operation, in which each map_op is transformed into the necessary "insert" or "delete" mutators. Then the "mutate" operation is added to the operations that will be send to the server. Once the transaction is finished, all map operation lists are cleared and deleted, so the next transaction starts with a clean board for map operations. Using different structures and logic to handle map operations, instead of trying to force the current structures (like 'old' and 'new' datums in the row) to handle then, ensures that map operations won't mess up with the current logic to generate JSON messages for other operations, avoids duplicating the whole map for just a few changes, and is faster for insert and delete operations, because there is no need to maintain the invariants in the 'new' datum. Signed-off-by: Edward Aymerich <edward.aymerich@hpe.com> Signed-off-by: Arnoldo Lutz <arnoldo.lutz.guevara@hpe.com> Co-authored-by: Arnoldo Lutz <arnoldo.lutz.guevara@hpe.com> [blp@ovn.org made style changes and factored out error checking] Signed-off-by: Ben Pfaff <blp@ovn.org>
2016-05-02 13:59:44 -06:00
/* Copyright (C) 2016 Hewlett Packard Enterprise Development LP
 * All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
#ifndef OVSDB_MAP_OP_H
#define OVSDB_MAP_OP_H 1
#include "ovsdb-data.h"
#ifdef __cplusplus
extern "C" {
#endif
ovsdb-idl: Add partial map updates functionality. In the current implementation, every time an element of either a map or set column has to be modified, the entire content of the column is sent to the server to be updated. This is not a major problem if the information contained in the column for the corresponding row is small, but there are cases where these columns can have a significant amount of elements per row, or these values are updated frequently, therefore the cost of the modifications becomes high in terms of time and bandwidth. In this solution, the ovsdb-idl code is modified to use the RFC 7047 'mutate' operation, to allow sending partial modifications on map columns to the server. The functionality is exposed to clients in the vswitch idl. This was implemented through map operations. A map operation is defined as an insertion, update or deletion of a key-value pair inside a map. The idea is to minimize the amount of map operations that are send to the OVSDB server when a transaction is committed. In order to keep track of the requested map operations, structs map_op and map_op_list were defined with accompanying functions to manipulate them. These functions make sure that only one operation is send to the server for each key-value that wants to be modified, so multiple operation on a key value are collapsed into a single operation. As an example, if a client using the IDL updates several times the value for the same key, the functions will ensure that only the last value is send to the server, instead of multiple updates. Or, if the client inserts a key-value, and later on deletes the key before committing the transaction, then both actions cancel out and no map operation is send for that key. To keep track of the desired map operations on each transaction, a list of map operations (struct map_op_list) is created for every column on the row on which a map operation is performed. When a new map operation is requested on the same column, the corresponding map_op_list is checked to verify if a previous operations was performed on the same key, on the same transaction. If there is no previous operation, then the new operation is just added into the list. But if there was a previous operation on the same key, then the previous operation is collapsed with the new operation into a single operation that preserves the final result if both operations were to be performed sequentially. This design keep a small memory footprint during transactions. When a transaction is committed, the map operations lists are checked and all map operations that belong to the same map are grouped together into a single JSON RPC "mutate" operation, in which each map_op is transformed into the necessary "insert" or "delete" mutators. Then the "mutate" operation is added to the operations that will be send to the server. Once the transaction is finished, all map operation lists are cleared and deleted, so the next transaction starts with a clean board for map operations. Using different structures and logic to handle map operations, instead of trying to force the current structures (like 'old' and 'new' datums in the row) to handle then, ensures that map operations won't mess up with the current logic to generate JSON messages for other operations, avoids duplicating the whole map for just a few changes, and is faster for insert and delete operations, because there is no need to maintain the invariants in the 'new' datum. Signed-off-by: Edward Aymerich <edward.aymerich@hpe.com> Signed-off-by: Arnoldo Lutz <arnoldo.lutz.guevara@hpe.com> Co-authored-by: Arnoldo Lutz <arnoldo.lutz.guevara@hpe.com> [blp@ovn.org made style changes and factored out error checking] Signed-off-by: Ben Pfaff <blp@ovn.org>
2016-05-02 13:59:44 -06:00
enum map_op_type {
MAP_OP_UPDATE,
MAP_OP_INSERT,
MAP_OP_DELETE
};
struct map_op; /* Map Operation: a Partial Map Update */
struct map_op_list; /* List of Map Operations */
/* Map Operation functions */
struct map_op *map_op_create(struct ovsdb_datum *, enum map_op_type);
void map_op_destroy(struct map_op *, const struct ovsdb_type *);
struct ovsdb_datum *map_op_datum(const struct map_op*);
enum map_op_type map_op_type(const struct map_op*);
/* Map Operation List functions */
struct map_op_list *map_op_list_create(void);
void map_op_list_destroy(struct map_op_list *, const struct ovsdb_type *);
void map_op_list_add(struct map_op_list *, struct map_op *,
const struct ovsdb_type *);
struct map_op *map_op_list_first(struct map_op_list *);
struct map_op *map_op_list_next(struct map_op_list *, struct map_op *);
#ifdef __cplusplus
}
#endif
ovsdb-idl: Add partial map updates functionality. In the current implementation, every time an element of either a map or set column has to be modified, the entire content of the column is sent to the server to be updated. This is not a major problem if the information contained in the column for the corresponding row is small, but there are cases where these columns can have a significant amount of elements per row, or these values are updated frequently, therefore the cost of the modifications becomes high in terms of time and bandwidth. In this solution, the ovsdb-idl code is modified to use the RFC 7047 'mutate' operation, to allow sending partial modifications on map columns to the server. The functionality is exposed to clients in the vswitch idl. This was implemented through map operations. A map operation is defined as an insertion, update or deletion of a key-value pair inside a map. The idea is to minimize the amount of map operations that are send to the OVSDB server when a transaction is committed. In order to keep track of the requested map operations, structs map_op and map_op_list were defined with accompanying functions to manipulate them. These functions make sure that only one operation is send to the server for each key-value that wants to be modified, so multiple operation on a key value are collapsed into a single operation. As an example, if a client using the IDL updates several times the value for the same key, the functions will ensure that only the last value is send to the server, instead of multiple updates. Or, if the client inserts a key-value, and later on deletes the key before committing the transaction, then both actions cancel out and no map operation is send for that key. To keep track of the desired map operations on each transaction, a list of map operations (struct map_op_list) is created for every column on the row on which a map operation is performed. When a new map operation is requested on the same column, the corresponding map_op_list is checked to verify if a previous operations was performed on the same key, on the same transaction. If there is no previous operation, then the new operation is just added into the list. But if there was a previous operation on the same key, then the previous operation is collapsed with the new operation into a single operation that preserves the final result if both operations were to be performed sequentially. This design keep a small memory footprint during transactions. When a transaction is committed, the map operations lists are checked and all map operations that belong to the same map are grouped together into a single JSON RPC "mutate" operation, in which each map_op is transformed into the necessary "insert" or "delete" mutators. Then the "mutate" operation is added to the operations that will be send to the server. Once the transaction is finished, all map operation lists are cleared and deleted, so the next transaction starts with a clean board for map operations. Using different structures and logic to handle map operations, instead of trying to force the current structures (like 'old' and 'new' datums in the row) to handle then, ensures that map operations won't mess up with the current logic to generate JSON messages for other operations, avoids duplicating the whole map for just a few changes, and is faster for insert and delete operations, because there is no need to maintain the invariants in the 'new' datum. Signed-off-by: Edward Aymerich <edward.aymerich@hpe.com> Signed-off-by: Arnoldo Lutz <arnoldo.lutz.guevara@hpe.com> Co-authored-by: Arnoldo Lutz <arnoldo.lutz.guevara@hpe.com> [blp@ovn.org made style changes and factored out error checking] Signed-off-by: Ben Pfaff <blp@ovn.org>
2016-05-02 13:59:44 -06:00
#endif /* ovsdb-map-op.h */