Parsing data into a module-level mutable static variable - static

I have a set of functions within a module that need access to some shared initialization-time state. Effectively I'd like to model this with a static mutable vector like:
static mut defs: Vec<String> = vec![];
fn initialize() {
defs.push("One".to_string());
defs.push("Two".to_string());
}
(Example: http://is.gd/TyNQVv, fails with "mutable statics are not allowed to have destructors".)
My question is similar to Is it possible to use global variables in Rust?, but uses a Vec (i.e. a type with destructor), so the Option-based solution to that question doesn't seem to apply. Namely, this fails with the same error as my first attempt:
static mut defs: Option<Vec<String>> = None;
fn initialize() {
let init_defs = vec![];
init_defs.push("One".to_string());
init_defs.push("Two".to_string());
defs = Some(init_defs);
}
Is there a way to get access to a static ("global") vector that is populated at initialization time and visible at runtime?
Are there other patterns I should be considering to support this use case? Passing explicit references to the state vector is possible, but would clutter up a very large number of function signatures that all need access to this state.

You can use lazy_static for this purpose:
lazy_static! {
static ref defs: Vec<String> = {
let mut init = vec!["One".to_string(), "Two".to_string()];
// init.push(...); etc. etc.
init
}
}
That initialises a vector on the first access, and it is immutable after that. If you wish to modify it later, wrapping it in a std::sync::Mutex is a good first step.
Are there other patterns I should be considering to support this use case? Passing explicit references to the state vector is possible, but would clutter up a very large number of function signatures that all need access to this state.
One pattern to consider is creating a context object that stores all the info the functions need, e.g.
struct Context {
defs: Vec<String>
}
and then passing around Context ensures everyone knows what they need to know. You can even consider putting all/many/some of the functions as methods on Context, e.g.
impl Context {
fn foo(&self) {
if self.defs.len() > 10 {
println!("lots of defs");
}
}
// ...
}
This pattern is especially good if you need to modify the context (automatically ensures thread safety), and/or if you wish to have several independent instances in a single process.

Related

How do I declare global variables in Pact lang?

I'm writing a smart contract and I want to declare global variables. I want the functions in my smart contract to be able to access and update these variables.
For example, in Solidity I can do this as follows:
pragma solidity ^0.5.0;
contract SolidityTest {
uint someSmartContractVar; // State variable
constructor() public {
someSmartContractVar = 10; // Setting the variable
}
...
}
I see the coin contract makes use of defconst here:
(defconst COIN_CHARSET CHARSET_LATIN1
"The default coin contract character set")
This approach is good for variables that need to be accessible by the rest of the contract, but I don't think I can change the values of these variables at some later point.
One possibility is creating a table named "global-variables" and storing the specific variables there. So then the functions can access and change these variables via table reads and updates. For example:
(defschema global-variable-schema
someSmartContractVar:decimal)
(deftable global-variables:{global-variable-schema})
(defconst GLOBAL_VAR_KEYNAME "global-vars")
(defun constructor:string ()
(insert global-variables GLOBAL_VAR_KEYNAME
{ 'someSmartContractVar: 10.0 }
)
"Global variables set"
)
(defun get-someSmartContractVar:decimal ()
(at "someSmartContractVar" (read global-variables GLOBAL_VAR_KEYNAME))
)
Is this the recommended approach for this type of use case?
Great question and that solution should work!
I don't know of any other practical way to do it.

Iterate through an array in an array of dictionaries swift

I am currently in a bit of a bind.
struct sectionWithDatesAsName {
var sectionName : String
var sectionObjects : [SoloTransactionModel]!
init(uniqueSectionName: String?, sectionObject: [SoloTransactionModel]?) {
sectionName = uniqueSectionName ?? "nil"
if let section = sectionObject {
sectionObjects = section.reversed()
}
}
}
I currently have an array of sectionWithDatesAsName. And I can work with it, display in the tableView among other things.
The bind comes up when I want to check some information in the sectionObject before displaying it on the tableView.
I want to check the type of the sectionObject which is saved in the object itself.
How do I check the information in the sectionObject without slowing down the app? Or have a horrible time complexity calculated?
(Note: I can't change the format of the struct has this has already been used by a whole lot of other processes)
Write a function in your sectionWithDatesAsName with the signature filteredSections(type: sectionType) -> sectionWithDatesAsName
(If you don't have the ability to edit the definition of sectionWithDatesAsName you can create an extension that adds the above function)
If the sectionWithDatesAsName is defined elsewhere, define this function in an extension.
When you call it, build a new sectionWithDatesAsName object by filtering the arrays to match the specified type.
Use the resulting filtered sectionWithDatesAsName object as the data model for your table view. It will be built once and used for the lifetime of the tableView, so you will pay an O(n) time cost to filter it once when you create it.

Swift Array multiple appending on click

I'm creating a button that when clicked adds the current date and time to an array but when I try to append to the array it only appends once and not repeating the process
the Entries struct:
struct Enteries {
var dates:[String] = []
}
convert date to String:
func DateConverter(){
format.timeZone = .current
format.dateFormat = "yyyy-MM-dd HH:mm"
dateString = format.string(from: currentDate)
}
The function that appends: also its called later whenever an IBAction is triggered
func AddToDatabase () {
var entery = Enteries()
entery.dates.append(dateString)
print(entery.dates)
}
`
Yikes, there's a lot going on here.
First of all, Swift's convention is to use lowerCamelCase for functions. Only type names should be UpperCamelCase.
Secondly, function names should be verbs or verb phrases, type names should be nouns. If I saw DateConverter in some code, I would expect it to be a type. It's an UpperCamelCase noun, that's how types should be named. But yours is a function (which would be a total surprise to every other Swift developer, because it violates the expectations they've built up from Swift's naming conventions), that function should probably be called parseDate.
Which way does DateConverter convert? From String to Date, Date to String, or both? What's its input? What's it's output? These things should be obvious from a good function name, but are totally unknown here without looking at the implementation.
Critically, the DateConverter function doesn't take input from parameters, and doesn't return a result, instead it takes input from a side effect (accessing the variable currentDate) and returns a result via side effect (writing to an a variable dateString). This is really bad, for several reasons:
It's not reusable. You have no way to use this date parsing code somewhere else without copy/pasting it, which is how code duplication and complexity arise. If you ever decide to change the date format in your app, you won't have a central source-of-truth that you can change, instead you'll have to manually hunt down every copy of this function, and change it, hoping you don't miss any. Not good.
It's not thread safe
It's more complex than a simple function that has type (Date) -> String. It obfuscates what's going on.
It defies peoples' expectations, without justification.
Enteries.dates has a default value of [], which doesn't seem to be a good idea if you're going to be appending to it as soon as you create it. Instead, take the array via an initializer parameter.
Enteries.dates has type [String]. Why?! You already have Date objects, store those!
They're smaller (in memory)
They're presentation-agnostic, meaning you can properly format them for different interfaces and different locales at a later time, as necessary
They support date math. I often see people storing dates as strings, and ask questions like "How do I sort my array of dates?" (which are actually stored as strings), "How do I add 1 day to "2019-12-24", and they start doing funky parsing, splitting, joining, and it's all just an absolute mess
Here's how I would improve this code:
struct Entries {
var entries: [Entry]
}
struct Entry {
let date: Date
}
// Call this from your view layer, only when you're about to present a `Date` to a user.
func parse(date: Date) -> String {
let df = DateFormatter()
df.timeZone = .current
df.dateFormat = "yyyy-MM-dd HH:mm"
return format.string(from: currentDate)
}
var entries = Entries(entries: [])
func addToDatabase(entry: Entry) {
entries.append(entry)
print(enteries.entries)
}
you are creating a new entery object eveytime the function is called. SO its creating a new object everytime. Declare your entery object outside the function.
var entery = Enteries()
func AddToDatabase () {
entery.dates.append(dateString)
print(entery.dates)
}

Swift can't call self from c callback in linphone sdk

I have problem when try to call Swift instance method from c callback.
Error: "A C function pointer cannot be formed from a closure that captures context."
linphone_core_cbs_set_registration_state_changed(cbs) { (lc, cfg, state, message) in
switch state{
case LinphoneRegistrationOk:
print("LinphoneRegistrationOk")
self.call()
}
func call() {
let account = "test"
let domain = "sip.linphone.org"
let identity = "sip:" + account + "#" + domain
linphone_core_invite(lc, identity)
}
If you have the ability to pass an arbitrary void* as a context then using Unmanaged<SelfType>.passUnretained(self).toOpaque() and converting it back with Unmanaged<SelfType>.fromOpaque(context).takeUnretainedValue() is the best solution.
But based on your small snippet of (lc, cfg, state, message) none of them seem like a context pointer. So getting self back is still possible but likely more complex. Because you will need to create a global/static piece of data that can be accessed from inside your closure in a safe manner. Some ideas of how you can do this are below:
1) You can do this with just a simple global/static if you know that is safe.
2) You can use thread local storage and store a pointer to self and cast it back and forth in the same way as if you had the void* argument and used Unmanaged. This one of course requires that your C callback be raised on the same thread where you store the value.
3) If you have access to a unique identifier that both Swift and C can access that will continue to be valid and accessible in your callback you can create a map of type [UniqueIdentifierAccessibleBySwiftAndC: TypeOfSelf] and use that to get self back.

How to define thread safe array?

How can I define a thread safe global array with minimal modifications?
I want like every access to it to be accomplished by using mutex and synchronized block.
Something like this as 'T' will be some type (note that 'sync' keyword is not currently defined AFAIK):
sync Array!(T) syncvar;
And every access to it will be simmilar to this:
Mutex __syncvar_mutex;
//some func scope....
synchronized(__syncvar_mutex) { /* edits 'syncvar' safely */ }
My naive attempt was to do something like this:
import std.typecons : Proxy:
synchronized class Array(T)
{
static import std.array;
private std.array.Array!T data;
mixin Proxy!data;
}
Sadly, it doesn't work because of https://issues.dlang.org/show_bug.cgi?id=14509
Can't say I am very surprised though as automagical handling of multi-threading via hidden mutexes is very unidiomatic in modern D and the very concept of synchronized classes is mostly a relict from D1 times.
You can implement same solution manually, of course, by defining own SharedArray class with all necessary methods and adding locks inside the methods before calling internal private plain Array methods. But I presume you want something that work more out of the box.
Can't invent anything better right here and now (will think about it more) but it is worth noting that in general it is encouraged in D to create data structures designed for handling shared access explicitly instead of just protecting normal data structures with mutexes. And, of course, most encouraged approach is to not shared data at all using message passing instead.
I will update the answer if anything better comes to my mind.
It is fairly easy to make a wrapper around array that will make it thread-safe. However, it is extremely difficult to make a thread-safe array that is not a concurrency bottleneck.
The closest thing that comes to mind is Java's CopyOnWriteArrayList class, but even that is not ideal...
You can wrap the array inside a struct that locks the access to the array when a thread acquires a token and until it releases it.
The wrapper/locker:
acquire(): is called in loop by a thread. As it returns a pointer, the thread knows that it has the token when the method returns a non null value.
release(): is called by a thread after processing the data whose access has been acquired previously.
.
shared struct Locker(T)
{
private:
T t;
size_t token;
public:
shared(T) * acquire()
{
if (token) return null;
else
{
import core.atomic;
atomicOp!"+="(token, 1);
return &t;
}
}
void release()
{
import core.atomic;
atomicOp!"-="(token, 1);
}
}
and a quick test:
alias LockedIntArray = Locker!(size_t[]);
shared LockedIntArray intArr;
void arrayTask(size_t cnt)
{
import core.thread, std.random;
// ensure the desynchronization of this job.
Thread.sleep( dur!"msecs"(uniform(4, 20)));
shared(size_t[])* arr = null;
// wait for the token
while(arr == null) {arr = intArr.acquire;}
*arr ~= cnt;
import std.stdio;
writeln(*arr);
// release the token for the waiting threads
intArr.release;
}
void main(string[] args)
{
import std.parallelism;
foreach(immutable i; 0..16)
{
auto job = task(&arrayTask, i);
job.executeInNewThread();
}
}
With the downside that each block of operation over the array must be surrounded with an acquire/release pair.
You have the right idea. As an array, you need to be able to both edit and retrieve information. I suggest you take a look at the read-write mutex and atomic utilities provided by Phobos. A read operation is fairly simple:
synchronize on mutex.readLock
load (with atomicLoad)
copy the item out of the synchronize block
return the copied item
Writing should be almost exactly the same. Just syncronize on mutex.writeLock and do a cas or atomicOp operation.
Note that this will only work if you copy the elements in the array during a read. If you want to get a reference, you need to do additional synchronization on the element every time you access or modify it.

Resources