UnorderedMap returns Out of Bounds error when inserting in NEAR - nearprotocol

I'm currently having an issue with inserting a key-value pair in NEAR Protocol for Unorderedmap.
Here's my pseudocode:
let mut new_list: UnorderedMap<String, Struct> = UnorderedMap::new(b"m");
// iterate through old list
for (key, data) in old_list.iter() {
let new_data_to_push = Struct {
data: old_data.data,
};
new_list.insert(&key, &new_data_to_push);
}
I'm migrating data from an old list to a new list with new data for a migrate function.
I can't seem to figure out why there is an Out of Bounds error for an UnorderedMap.

We discovered that if you migrate an UnorderedMap, it should contain a totally new name and not the same name again and again. Hence, Index Out of Bounds issue will occur because it accesses the same Map due to the same name.

Related

How does Apollo paginated "read" and "merge" work?

I was reading through the docs to learn pagination approaches for Apollo. This is the simple example where they explain the paginated read function:
https://www.apollographql.com/docs/react/pagination/core-api#paginated-read-functions
Here is the relevant code snippet:
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
feed: {
read(existing, { args: { offset, limit }}) {
// A read function should always return undefined if existing is
// undefined. Returning undefined signals that the field is
// missing from the cache, which instructs Apollo Client to
// fetch its value from your GraphQL server.
return existing && existing.slice(offset, offset + limit);
},
// The keyArgs list and merge function are the same as above.
keyArgs: [],
merge(existing, incoming, { args: { offset = 0 }}) {
const merged = existing ? existing.slice(0) : [];
for (let i = 0; i < incoming.length; ++i) {
merged[offset + i] = incoming[i];
}
return merged;
},
},
},
},
},
});
I have one major question around this snippet and more snippets from the docs that have the same "flaw" in my eyes, but I feel like I'm missing some piece.
Suppose I run a first query with offset=0 and limit=10. The server will return 10 results based on this query and store it inside cache after accessing merge function.
Afterwards, I run the query with offset=5 and limit=10. Based on the approach described in docs and the above code snippet, what I'm understanding is that I will get only the items from 5 through 10 instead of items from 5 to 15. Because Apollo will see that existing variable is present in read (with existing holding initial 10 items) and it will slice the available 5 items for me.
My question is - what am I missing? How will Apollo know to fetch new data from the server? How will new data arrive into cache after initial query? Keep in mind keyArgs is set to [] so the results will always be merged into a single item in the cache.
Apollo will not slice anything automatically. You have to define a merge function that keeps the data in the correct order in the cache. One approach would be to have an array with empty slots for data not yet fetched, and place incoming data in their respective index. For instance if you fetch items 30-40 out of a total of 100 your array would have 30 empty slots then your items then 60 empty slots. If you subsequently fetch items 70-80 those will be placed in their respective indexes and so on.
Your read function is where the decision on whether a network request is necessary or not will be made. If you find all the data in existing you will return them and no request to the server will be made. If any items are missing then you need to return undefined which will trigger a network request, then your merge function will be triggered once data is fetched, and finally your read function will run again only this time the data will be in the cache and it will be able to return them.
This approach is for the cache-first caching policy which is the default.
The logic for returning undefined from your read function will be implemented by you. There is no apollo magic under the hood.
If you use cache-and-network policy then a your read doesn't need to return undefined when data

SWIFT OS X - deleting managed objects from persistent store: fatal error

I am using the function below to delete managed objects from a persistent store.
The deletion function is:
func deletePPRRowDataManagedObject(date: NSDate) {
let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName(self.pprRowEntity, inManagedObjectContext: self.managedObjectContext!) as! PPRRowData
var pprRowDataArray = self.fetchPPRRowDataManagedObjects()
let filteredPPRRowDataArray = pprRowDataArray.filter({$0.pprDate == date})
for object in filteredPPRRowDataArray {
managedObjectContext?.deleteObject(object)
}
var pprFileDataArray = self.fetchPPRFileDataManagedObjects()
let filteredPPRFileDataArray = pprFileDataArray.filter({$0.pprDate == date})
for object in filteredPPRFileDataArray {
managedObjectContext?.deleteObject(object)
}
var error: NSError? = nil
if !managedObjectContext!.save(&error) {
// this code needs to be replaced to properly deal with the error
abort()
}
}
I have three subclassed Core Data entities of which I am trying to delete managed objects from the persistent store for two them in this code.
There are no relationships defined between the three entities. All three are saved within the same managed object context and the same persistent store.
After I have deleted the managed objects I can create and fetch data from the persistent store without a runtime error. I can access data from the third entity but now get a data fault when i try to access the data arrays created from the fetch..... functions that source the managed objects from the persistent store for the two entities that I have deleted some managed objects for.
The code (below) to fetch the data from the persistent store runs without error. The error
(EXC_BAD_ACCESS (code=1, address=0x0) error)
occurs when I try to access the outputArray.
let outputArray = addDataFiles.fetchPPRRowDataManagedObjects()
When I run the code prior to any deletions it runs without any problems.
Any thoughts/guidance on what may be creating the error would be appreciated. I have not been able to determine if it is a problem with the code I am using to delete the managed objects or the relevant fetch... function that I am using.
The following is an example of one of the fetch... functions that I am using:
func fetchPPRRowDataManagedObjects() ->Array<PPRRowData>{
let fetchRequestPPRRowData = NSFetchRequest()
let entityPPRRowData = NSEntityDescription.entityForName(self.pprRowEntity, inManagedObjectContext: self.managedObjectContext!)
var resultsArrayPPRRowData: Array<PPRRowData> = []
var arrayFetchResults: Array<AnyObject> = []
fetchRequestPPRRowData.entity = entityPPRRowData
var error: NSError? = nil
arrayFetchResults = managedObjectContext!.executeFetchRequest(fetchRequestPPRRowData, error: &error)!
for index in arrayFetchResults {
resultsArrayPPRRowData.append(index as! PPRRowData)
}
return resultsArrayPPRRowData
}
Ok - after a lot of code testing, I have identified the problem was an erroneous !managedObjectContext!.save() statement that was firing within the loop as I was iterating through the code - both in the createManagedObject() function and in the .deleteManagedObject() function that I had created. Not even sure why it was there (that is, why I had put it there in the first place) but it was obviously creating the problem.
Marcus, many thanks for your patience and suggestions, it led to me reviewing my code more closely and eventually identifying the problem. – Wolfstar 1 hour ago

Getting the objects with similar secondary index in Riak?

Is there a way to get all the objects in key/value format which are under one similar secondary index value. I know we can get the list of keys for one secondary index (bucket/{{bucketName}}/index/{{index_name}}/{{index_val}}). But somehow my requirements are such that if I can get all the objects too. I don't want to perform a separate query for each key to get the object details separately if there is way around it.
I am completely new to Riak and I am totally a front-end guy, so please bear with me if something I ask is of novice level.
In Riak, it's sometimes the case that the better way is to do separate lookups for each key. Coming from other databases this seems strange, and likely inefficient, however you may find your query will be faster over an index and a bunch of single object gets, than a map/reduce for all the objects in a single go.
Try both these approaches, and see which turns out fastest for your dataset - variables that affect this are: size of data being queried; size of each document; power of your cluster; load the cluster is under etc.
Python code demonstrating the index and separate gets (if the data you're getting is large, this method can be made memory-efficient on the client, as you don't need to store all the objects in memory):
query = riak_client.index("bucket_name", 'myindex', 1)
query.map("""
function(v, kd, args) {
return [v.key];
}"""
)
results = query.run()
bucket = riak_client.bucket("bucket_name")
for key in results:
obj = bucket.get(key)
# .. do something with the object
Python code demonstrating a map/reduce for all objects (returns a list of {key:document} objects):
query = riak_client.index("bucket_name", 'myindex', 1)
query.map("""
function(v, kd, args) {
var obj = Riak.mapValuesJson(v)[0];
return [ {
'key': v.key,
'data': obj,
} ];
}"""
)
results = query.run()

Select one unique instance from LINQ query

I'm using LINQ to SQL to obtain data from a set of database tables. The database design is such that given a unique ID from one table (Table A) one and only one instance should be returned from an associated table (Table B).
Is there a more concise way to compose this query and ensure that only one item was returned without using the .Count() extension method like below:
var set = from itemFromA in this.dataContext.TableA
where itemFromA.ID == inputID
select itemFromA.ItemFromB;
if (set.Count() != 1)
{
// Exception!
}
// Have to get individual instance using FirstOrDefault or Take(1)
FirstOrDefault helps somewhat but I want to ensure that the returned set contains only one instance and not more.
It sounds like you want Single:
var set = from itemFromA in this.dataContext.TableA
where itemFromA.ID == inputID
select itemFromA.ItemFromB;
var onlyValue = set.Single();
Documentation states:
Returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence.
Of course that means you don't get to customize the message of the exception... if you need to do that, I'd use something like:
// Make sure that even if something is hideously wrong, we only transfer data
// for two elements...
var list = set.Take(2).ToList();
if (list.Count != 1)
{
// Throw an exception
}
var item = list[0];
The benefit of this over your current code is that it will avoid evaluating the query more than once.

How to instantiate an object within a linq query

This is kinda theoretical question,
I was looking at someone else' code (below) and my simple solution was to instantiate the collection outside linq, but I can guess there will be cases where I'd want to instantiate the objects inside the query, and perhaps only on a selection of elements.
Here's a simplified example of how this was being done (badly).
var pods = (from n in ids
where new Node(Convert.ToInt32(n)).HasValue("propertyName")
select new
{
Id = Convert.ToInt32(n),
Url = new Node(Convert.ToInt32(n)).Url,
Name = new Node(Convert.ToInt32(n)).Title()
}).ToList();
Irrelevant Note: in this case the Node constructor is getting data from a memory cache.
How can I improve this example to only instantiate each object once using linq?
Cheers.
Murray.
Use a let clause like this:
var pods = (
from n in ids
let id = Convert.ToInt32(n)
let node = new Node(id)
where node.HasValue("propertyName")
select new
{
Id = id,
Url = node.Url,
Name = node.Title()
}
).ToList();
For more information please see let clause (C# Reference):
In a query expression, it is sometimes
useful to store the result of a
sub-expression in order to use it in
subsequent clauses. You can do this
with the let keyword, which creates a
new range variable and initializes it
with the result of the expression you
supply. Once initialized with a value,
the range variable cannot be used to
store another value. However, if the
range variable holds a queryable type,
it can be queried.

Resources