1/*
2 * udf_record.h
3 *
4 * Copyright (C) 2013-2015 Aerospike, Inc.
5 *
6 * Portions may be licensed to Aerospike, Inc. under one or more contributor
7 * license agreements.
8 *
9 * This program is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU Affero General Public License as published by the Free
11 * Software Foundation, either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see http://www.gnu.org/licenses/
21 */
22
23#pragma once
24
25#include <stdbool.h>
26#include <stddef.h>
27#include <stdint.h>
28
29#include "aerospike/as_rec.h"
30#include "aerospike/as_hashmap.h"
31#include "aerospike/as_val.h"
32#include "citrusleaf/cf_atomic.h"
33
34#include "base/datamodel.h"
35#include "base/transaction.h"
36#include "base/xdr_serverside.h"
37#include "storage/storage.h"
38
39
40// Maximum number of bins that can be updated in a single UDF.
41#define UDF_RECORD_BIN_ULIMIT 512
42
43typedef struct udf_record_bin_s {
44 char name[AS_BIN_NAME_MAX_SZ];
45 as_val * value;
46 bool dirty;
47 void *particle_buf;
48} udf_record_bin;
49
50typedef struct udf_record_s {
51
52 // STORAGE
53 as_index_ref *r_ref;
54 as_transaction *tr;
55 as_storage_rd *rd;
56 xdr_dirty_bins *dirty;
57 cf_digest keyd;
58 as_bin stack_bins[UDF_RECORD_BIN_ULIMIT]; // TODO increase bin limit?
59
60 // UDF CHANGE CACHE
61 udf_record_bin updates[UDF_RECORD_BIN_ULIMIT]; // stores cache bin value
62 // if dirty flag is set the bin is being modified
63 uint32_t nupdates; // reset after every cache free, incremented in every cache set
64
65 // RUNTIME ACCOUNTING
66 uint8_t *particle_data; // non-null for data-on-ssd, and lazy allocated on first bin write
67 uint8_t *cur_particle_data; // where the pointer is
68 uint8_t *end_particle_data;
69 uint32_t starting_memory_bytes;
70 cf_atomic_int udf_runtime_memory_used;
71
72 // INTERNAL UTILITY
73 uint16_t flag;
74
75 // PICKLE MADE BY STORAGE WRITE
76 // Note - must survive udf_record_close() to convey pickle to rw_request.
77 uint8_t *pickle;
78 uint32_t pickle_sz;
79} udf_record;
80
81#define UDF_RECORD_FLAG_ALLOW_UPDATES 0x0001 // Write/Updates Allowed
82#define UDF_RECORD_FLAG_TOO_MANY_BINS 0x0002 // UDF exceeds the bin limit
83#define UDF_RECORD_FLAG_UNUSED_4 0x0004 // was - sub-record
84#define UDF_RECORD_FLAG_OPEN 0x0008 // as_record_open done
85#define UDF_RECORD_FLAG_STORAGE_OPEN 0x0010 // as_storage_record_open done
86#define UDF_RECORD_FLAG_HAS_UPDATES 0x0020 // Write/Update done
87#define UDF_RECORD_FLAG_PREEXISTS 0x0040 // Record preexisted not created
88#define UDF_RECORD_FLAG_ISVALID 0x0080 // Udf is setup and in use
89#define UDF_RECORD_FLAG_METADATA_UPDATED 0x0100 // Write/Update metadata done
90
91extern const as_rec_hooks udf_record_hooks;
92
93//------------------------------------------------
94// Utility functions for all the wrapper as_record implementation
95// which use udf_record under the hood
96extern void udf_record_cache_free (udf_record *);
97extern int udf_record_open (udf_record *);
98extern int udf_storage_record_open (udf_record *);
99extern void udf_record_close (udf_record *);
100extern int udf_storage_record_close(udf_record *);
101extern void udf_record_init (udf_record *, bool);
102extern as_val * udf_record_storage_get (const udf_record *, const char *);
103
104#define UDF_ERR_INTERNAL_PARAMETER 2
105#define UDF_ERR_RECORD_NOT_VALID 3
106#define UDF_ERR_PARAMETER 4
107extern int udf_record_param_check(const as_rec *rec, char *fname, int lineno);
108extern bool udf_record_destroy(as_rec *rec);
109
110//------------------------------------------------
111// Note that the main interface routines do NOT get declared here.
112// extern int udf_record_set_flags(const as_rec *, const char *, uint8_t);
113// extern int udf_record_set_type(const as_rec *, int8_t);
114