0

I am trying to add/update a couch base lite db fetching data from a remote server as batches But I get the following error when try to add the data to the DB, I don't get it in the first iteration.

at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)
at Couchbase.Lite.Database.GetDocument(String id)
at Couchbase.Lite.Database.GetExistingDocument(String id)
at Sys.Offline.DAL.CouchInventoryRepository.

My call is as below

public  bool FullSync()
{
    IInventoryFetcher fullfetcher = new InventoryFetcher();
    SyncData data=null;          

    do
    {
        var bucket = new ConcurrentDictionary<string, 
        ConcurrentDictionary<string, object>>();
        var skubucket = new ConcurrentDictionary<string,
        ConcurrentDictionary<string, object>>();

        // Create bucket dictionaries 
        for (int slot = 0; slot < 100; slot++)
        {
             bucket.TryAdd(slot.ToString() + _bucketDocSuffix, new 
             ConcurrentDictionary<string, object>());
             skubucket.TryAdd(slot.ToString() + _bucketDocSuffixSku, new
             ConcurrentDictionary<string, object>());
         }

         data = fullfetcher.GetInventory();

         if(data == null) break;

         // For each UPC item calculate the bucket 
         Parallel.ForEach(data.UPCSkuMap, item =>
         {                    
              // calculate the bucket slot
              var bucketSlot = (int)(Int64.Parse(item.Key.Substring(5, 6)) % 100);

              if (!bucket[bucketSlot.ToString() + 
              _bucketDocSuffix].TryAdd(item.Key, item.Value))
                {
                    //if (!bucket[bucketSlot.ToString() + 
                    _bucketDocSuffix].ContainsKey(item.Key))
                        System.Diagnostics.Debugger.Break();
                }
            });


            Parallel.ForEach(data.SkuMap, item =>
            {

                // calculate the bucket slot
                var bucketSlot = (int)(Int64.Parse(item.Value[_slotfield].ToString()) % 100);

                if (!skubucket[bucketSlot.ToString() + 
                    _bucketDocSuffixSku].TryAdd(item.Key, item.Value))
                {
                    //if (!bucket[bucketSlot.ToString() + _bucketDocSuffix].ContainsKey(item.Key))
                    System.Diagnostics.Debugger.Break();
                }
            });

          if(! _database.RunInTransaction(new RunInTransactionDelegate(() =>
          {
                 return UpdateData(bucket, skubucket);
          })))
            {
                //TODO Log
            }          
        } while (!data.IsCompleted);

        return true;
}

public bool UpdateData(IDictionary<string, ConcurrentDictionary<string, object>> itemDictionary, IDictionary<string, ConcurrentDictionary<string, object>> skuDictionary)
{
    try
    {

        Parallel.ForEach(itemDictionary, item =>
        {
             if (item.Value.Count == 0) return;
             Document document=null;
             try
             {
                  document = _database.GetExistingDocument(item.Key);
             }
             catch(IndexOutOfRangeException ex)
             {
                 System.Diagnostics.Debugger.Break();
             }

             if (document == null)
                    document = _database.GetDocument(item.Key);
             else
                 if (!item.Value.TryAdd("_rev", document.CurrentRevisionId))
                 {
                     System.Diagnostics.Debugger.Break();
                 }

             var rev = document.PutProperties(item.Value);
         });

         Parallel.ForEach(skuDictionary, item =>
         {
             if (item.Value.Count == 0) return;
             var document = _database.GetExistingDocument(item.Key);

             if (document == null)
                 document = _database.GetDocument(item.Key);
             else
                 if (!item.Value.TryAdd("_rev", document.CurrentRevisionId))
                 {
                     System.Diagnostics.Debugger.Break();
                 }

             var rev = document.PutProperties(item.Value);
         });
     }
     catch (CouchbaseLiteException chEX) 
     {
         //TODO LOG...
         return false;  
     }
     return true;       
}

SyncData is as below

public class SyncData
{
    // key - sku , value - {"itemnumber":"0000000","AgeCode":null,"Hierarchy":"10925359","Id":"SK100000","Name":"CHRIS ABCD","Parent":"SKU00000","Price":"10","Taxcode":"NaN","Type":"6","upc":["924763541015","529713449709","883357620409"]}
    public IDictionary<string, JObject> SkuMap { get; private set; }

    // Key - UPC  value {skus:[{sku:xx,itemnumber:xxx}]}
    public IDictionary<string, JObject> UPCSkuMap { get; private set; }

    public bool IsCompleted { get; private set; }

    public SyncData(IDictionary<string, JObject> skuMap, IDictionary<string, JObject> upcSkuMap, bool isCompleted=false)
    {
        SkuMap = skuMap;
        UPCSkuMap = upcSkuMap;
        IsCompleted = isCompleted;

    }        
}
JNYRanger
  • 6,829
  • 12
  • 53
  • 81
jereesh thomas
  • 113
  • 1
  • 13
  • Is that the full stack trace? It looks incomplete. – borrrden Jul 29 '15 at 22:05
  • @borrrden , Yes the missing part is the call to UpdateData method - `public bool UpdateData(IDictionary> itemDictionary, IDictionary> skuDictionary)`-, I have used Parallel loop for accessing different documents , Isn't Couch Lite doc access API are not thread safe ? Actually I am accessing different document in each iteration of the loop that is why I used Parallel loop – jereesh thomas Jul 31 '15 at 07:09
  • I suggest filing this as an issue on the couchbase-lite-net github repo so I can remember to have a look at it later. – borrrden Jul 31 '15 at 13:36

0 Answers0