home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / rdf / src / remstore.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  11.4 KB  |  488 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /* 
  20.    This file implements remote store support for the rdf data model.
  21.    For more information on this file, contact rjc or guha 
  22.    For more information on RDF, look at the RDF section of www.mozilla.org
  23. */
  24.  
  25. #include "remstore.h"
  26. #include "hist2rdf.h"
  27. #include "fs2rdf.h"
  28. #include "pm2rdf.h"
  29. #include "rdf-int.h"
  30. #include "bmk2mcf.h"
  31.  
  32.     /* globals */
  33. RDFFile rdfFiles = 0;
  34.  
  35.  
  36.  
  37. RDFT
  38. MakeRemoteStore (char* url)
  39. {
  40.   if (startsWith("rdf:remoteStore", url)) {
  41.     if (gRemoteStore == 0) {
  42.       RDFT ntr = (RDFT)getMem(sizeof(struct RDF_TranslatorStruct));
  43.       ntr->assert = NULL;
  44.       ntr->unassert = NULL;
  45.       ntr->getSlotValue = remoteStoreGetSlotValue;
  46.       ntr->getSlotValues = remoteStoreGetSlotValues;
  47.       ntr->hasAssertion = remoteStoreHasAssertion;
  48.       ntr->nextValue = remoteStoreNextValue;
  49.       ntr->disposeCursor = remoteStoreDisposeCursor;
  50.       gRemoteStore = ntr;
  51.       ntr->url = copyString(url);
  52.       return ntr;
  53.     } else return gRemoteStore;
  54.   } else return NULL;
  55. }
  56.  
  57.  
  58.  
  59. RDFT
  60. MakeFileDB (char* url)
  61. {
  62.   if (endsWith(".rdf", url) || endsWith(".mcf", url)) {
  63.     if (gRemoteStore == 0) MakeRemoteStore("rdf:remoteStore");
  64.     if (!fileReadp(url, 1)) readRDFFile(url, NULL, 1);
  65.     return gRemoteStore;
  66.   } else return NULL;
  67. }
  68.  
  69.  
  70.  
  71. PRBool
  72. asEqual(Assertion as, RDF_Resource u, RDF_Resource s, void* v, 
  73.            RDF_ValueType type)
  74. {
  75.   return ((as->u == u) && (as->s == s) && (as->type == type) && 
  76.       ((as->value == v) || 
  77.        ((type == RDF_STRING_TYPE) && (strcmp(v, as->value) == 0))));
  78. }
  79.  
  80.  
  81.  
  82. Assertion
  83. makeNewAssertion (RDF_Resource u, RDF_Resource s, void* v, 
  84.                 RDF_ValueType type, PRBool tv)
  85. {
  86.   Assertion newAs = (Assertion) getMem(sizeof(struct RDF_AssertionStruct));
  87.   newAs->u = u;
  88.   newAs->s = s;
  89.   newAs->value = v;
  90.   newAs->type = type;
  91.   newAs->tv = tv;
  92.   return newAs;
  93. }
  94.  
  95.  
  96.  
  97. void
  98. freeAssertion (Assertion as)
  99. {
  100.   if (as->type == RDF_STRING_TYPE) {
  101.     freeMem(as->value);
  102.   } 
  103.   freeMem(as);
  104. }
  105.  
  106.  
  107.  
  108. PRBool
  109. remoteAssert3 (RDFFile fi, RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, 
  110.              RDF_ValueType type, PRBool tv)
  111. {
  112.   Assertion as = remoteStoreAdd(mcf, u, s, v, type, tv);
  113.   if (as != NULL) {
  114.     void addToAssertionList (RDFFile f, Assertion as) ;
  115.     addToAssertionList(fi, as);
  116.     return 1;
  117.   } else return 0;
  118. }
  119.  
  120.  
  121.  
  122. Assertion
  123. remoteStoreAdd (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, 
  124.               RDF_ValueType type, PRBool tv)
  125. {
  126.   Assertion nextAs, prevAs, newAs; 
  127.   nextAs = prevAs = u->rarg1;
  128.   
  129.   while (nextAs != null) {
  130.     if (asEqual(nextAs, u, s, v, type)) return null;
  131.     prevAs = nextAs;
  132.     nextAs = nextAs->next;
  133.   }
  134.   newAs = makeNewAssertion(u, s, v, type, tv);
  135.   if (prevAs == null) {
  136.     u->rarg1 = newAs;
  137.   } else {
  138.     prevAs->next = newAs;
  139.   }
  140.   if (type == RDF_RESOURCE_TYPE) {
  141.     nextAs = prevAs = ((RDF_Resource)v)->rarg2;
  142.     while (nextAs != null) {
  143.       prevAs = nextAs;
  144.       nextAs = nextAs->invNext;
  145.     }
  146.     if (prevAs == null) {
  147.       ((RDF_Resource)v)->rarg2 = newAs;
  148.     } else {
  149.       prevAs->invNext = newAs;
  150.     }
  151.   }
  152.   sendNotifications2(mcf, RDF_ASSERT_NOTIFY, u, s, v, type, tv);
  153.   return newAs;
  154. }
  155.  
  156.  
  157.  
  158. Assertion
  159. remoteStoreRemove (RDFT mcf, RDF_Resource u, RDF_Resource s,
  160.                  void* v, RDF_ValueType type)
  161. {
  162.   Assertion nextAs, prevAs, ans;
  163.   PRBool found = false;
  164.   nextAs = prevAs = u->rarg1;
  165.   while (nextAs != null) {
  166.     if (asEqual(nextAs, u, s, v, type)) {
  167.       if (prevAs == null) {
  168.     u->rarg1 = nextAs->next;
  169.       } else {
  170.     prevAs->next = nextAs->next;
  171.       }
  172.       found = true;
  173.       ans = nextAs;
  174.       break;
  175.     }
  176.     prevAs = nextAs;
  177.     nextAs = nextAs->next; 
  178.   }
  179.   if (found == false) return null;
  180.   if (type == RDF_RESOURCE_TYPE) {
  181.     nextAs = prevAs = ((RDF_Resource)v)->rarg2;
  182.     while (nextAs != null) {
  183.       if (nextAs == ans) {
  184.     if (prevAs == nextAs) {
  185.       ((RDF_Resource)v)->rarg2 = nextAs->invNext;
  186.     } else {
  187.       prevAs->invNext = nextAs->invNext;
  188.     }
  189.       }
  190.       prevAs = nextAs;
  191.       nextAs = nextAs->invNext;
  192.     }
  193.   }
  194.   sendNotifications2(mcf, RDF_DELETE_NOTIFY, u, s, v, type, ans->tv);
  195.   return ans;
  196. }
  197.  
  198.  
  199.  
  200. static PRBool
  201. fileReadp (char* url, PRBool mark)
  202. {
  203.   RDFFile f;
  204.   uint n = 0;
  205.   for (f = rdfFiles; (f != NULL) ; f = f->next) {
  206.     if (urlEquals(url, f->url)) {
  207.       if (mark == true)    f->lastReadTime = PR_Now();
  208.       return true;
  209.     }
  210.   }
  211.   return false;
  212. }
  213.  
  214.  
  215.  
  216. static void
  217. possiblyAccessFile (RDFT mcf, RDF_Resource u, RDF_Resource s, PRBool inversep)
  218. {
  219.   if ((s ==  gCoreVocab->RDF_parent) && inversep &&
  220.       ((u == gNavCenter->RDF_HistoryByDate) ||  (u ==  gNavCenter->RDF_HistoryBySite))) {
  221.     collateHistory(mcf->rdf->rdf, u, (u == gNavCenter->RDF_HistoryByDate));
  222.   } else if ((resourceType(u) == RDF_RT) && 
  223.          (s == gCoreVocab->RDF_parent) && (containerp(u)) && (strstr(resourceID(u), ":/") !=NULL) 
  224.            && (!fileReadp(resourceID(u), true))) {
  225.     RDFFile newFile = readRDFFile( resourceID(u), u, false);
  226.     if(newFile) newFile->lastReadTime = PR_Now();
  227.   }
  228. }
  229.  
  230.  
  231.  
  232. PRBool
  233. remoteStoreHasAssertionInt (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv)
  234. {
  235.   Assertion nextAs;
  236.   nextAs = u->rarg1;
  237.   while (nextAs != null) {
  238.     if (asEqual(nextAs, u, s, v, type) && (nextAs->tv == tv)) return true;
  239.     nextAs = nextAs->next;
  240.   }
  241.   possiblyAccessFile(mcf, u, s, 0);
  242.   return false;
  243. }
  244.  
  245.  
  246.  
  247. PRBool
  248. remoteStoreHasAssertion (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv)
  249. {
  250.   if (!((s == gCoreVocab->RDF_parent) && 
  251.     (type == RDF_RESOURCE_TYPE) && 
  252.     ((resourceType((RDF_Resource)v) == HISTORY_RT) ||
  253.      (resourceType((RDF_Resource)v) == ES_RT) ||
  254.      (resourceType((RDF_Resource)v) == FTP_RT)))) {
  255.       return remoteStoreHasAssertionInt(mcf, u, s, v, type, tv);
  256.     } else {
  257.       return 0;
  258.     }
  259. }
  260.  
  261.  
  262.  
  263. void *
  264. remoteStoreGetSlotValue (RDFT mcf, RDF_Resource u, RDF_Resource s, RDF_ValueType type, PRBool inversep,  PRBool tv)
  265. {
  266.   Assertion nextAs;
  267.   nextAs = (inversep ? u->rarg2 : u->rarg1);
  268.   while (nextAs != null) {
  269.     if ((nextAs->s == s) && (nextAs->tv == tv) && (nextAs->type == type)) {
  270.       void* ans = (inversep ? nextAs->u : nextAs->value);
  271.       if (type == RDF_STRING_TYPE) {
  272. #ifdef DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  273.     return copyString((char*)ans); 
  274. #else
  275.     return ans;
  276. #endif
  277.       } else return ans;
  278.     }
  279.     nextAs = (inversep ? nextAs->invNext : nextAs->next);
  280.   }
  281.   possiblyAccessFile(mcf, u, s, inversep);
  282.   return null;
  283. }
  284.  
  285.  
  286.  
  287. RDF_Cursor
  288. remoteStoreGetSlotValuesInt (RDFT mcf, RDF_Resource u, RDF_Resource s, RDF_ValueType type,  PRBool inversep, PRBool tv)
  289. {
  290.   Assertion as = (inversep ? u->rarg2 : u->rarg1);
  291.   RDF_Cursor c;
  292.   if (as == null) {
  293.     possiblyAccessFile(mcf, u, s, inversep);
  294.     as = (inversep ? u->rarg2 : u->rarg1);
  295.     if (as == NULL) return null;
  296.   }      
  297.   c = (RDF_Cursor)getMem(sizeof(struct RDF_CursorStruct));
  298.   c->u = u;
  299.   c->s = s;
  300.   c->type = type;
  301.   c->inversep = inversep;
  302.   c->tv = tv;
  303.   c->count = 0;
  304.   c->pdata = as;
  305.   return c;
  306. }
  307.  
  308.  
  309.  
  310. RDF_Cursor
  311. remoteStoreGetSlotValues (RDFT mcf, RDF_Resource u, RDF_Resource s, RDF_ValueType type,  PRBool inversep, PRBool tv)
  312. {
  313.   if (resourceType(u) == HISTORY_RT) return NULL;
  314.   return remoteStoreGetSlotValuesInt(mcf, u, s, type, inversep, tv);
  315. }
  316.  
  317.  
  318.  
  319. void *
  320. remoteStoreNextValue (RDFT mcf, RDF_Cursor c)
  321. {
  322.   while (c->pdata != null) {
  323.     Assertion as = (Assertion) c->pdata;
  324.     if ((as->s == c->s) && (as->tv == c->tv) && (c->type == as->type)) {
  325.       if (c->s == gCoreVocab->RDF_slotsHere) {
  326.     c->value = as->s;
  327.       } else { 
  328.     c->value = (c->inversep ? as->u : as->value);
  329.       }
  330.       c->pdata = (c->inversep ? as->invNext : as->next);
  331.       return c->value;
  332.     }
  333.     c->pdata = (c->inversep ? as->invNext : as->next);
  334.   }
  335.   
  336.   return null;
  337. }
  338.  
  339.  
  340.  
  341. RDF_Error
  342. remoteStoreDisposeCursor (RDFT mcf, RDF_Cursor c)
  343. {
  344.   freeMem(c);
  345.   return noRDFErr;
  346. }
  347.  
  348.  
  349.  
  350. static RDFFile
  351. leastRecentlyUsedRDFFile (RDF mcf)
  352. {
  353.   RDFFile lru = mcf->files;
  354.   RDFFile f;
  355. #ifndef HAVE_LONG_LONG
  356.   int64 result;
  357. #endif /* !HAVE_LONG_LONG */
  358.   for (f = mcf->files ; (f != NULL) ; f = f->next) {
  359.     if (!f->locked) {
  360. #ifndef HAVE_LONG_LONG
  361.       LL_SUB(result, lru->lastReadTime, f->lastReadTime);
  362.       if ((!LL_IS_ZERO(result) && LL_GE_ZERO(result)) && (f->localp == false))
  363. #else
  364.     if (((lru->lastReadTime - f->lastReadTime) > 0) && (f->localp == false))
  365. #endif /* !HAVE_LONG_LONG */
  366.       lru = f;
  367.     }
  368.   }
  369.   if (!lru->locked) {
  370.     return lru;
  371.   } else return NULL;
  372. }
  373.  
  374.  
  375.  
  376. void
  377. gcRDFFile (RDFFile f)
  378. {
  379.   int16 n = 0;
  380.   RDFFile f1;
  381.  
  382.   f1 = rdfFiles;
  383.   
  384.   if (f->locked) return;
  385.   
  386.   if (f == f1) {
  387.     rdfFiles = f->next;
  388.   } else {
  389.     RDFFile prev = f1;
  390.     while (f1 != NULL) {
  391.       if (f1 == f) {
  392.     prev->next = f->next;
  393.     break;
  394.       }
  395.       prev = f1;
  396.       f1 = f1->next;
  397.     }
  398.   }
  399.   
  400.   while (n < f->assertionCount) {
  401.     Assertion as = *(f->assertionList + n);
  402.     remoteStoreRemove(gRemoteStore, as->u, as->s, as->value, as->type);
  403.     freeAssertion(as);
  404.     *(f->assertionList + n) = NULL;
  405.     n++;
  406.   }
  407.   n = 0;
  408.   while (n < f->resourceCount) {
  409.     RDF_Resource u = *(f->resourceList + n);
  410.     possiblyGCResource(u);
  411.     n++;
  412.   }
  413.   freeMem(f->assertionList);
  414.   freeMem(f->resourceList);    
  415. }
  416.  
  417.  
  418.  
  419. static PRBool
  420. freeSomeRDFSpace (RDF mcf)
  421. {
  422.   RDFFile lru = leastRecentlyUsedRDFFile (mcf);
  423.   if (lru== NULL) {
  424.     return false;
  425.   } else {
  426.     gcRDFFile(lru);
  427.     freeMem(lru);
  428.     return true;
  429.   }
  430. }
  431.  
  432.  
  433.  
  434. RDFFile
  435. readRDFFile (char* url, RDF_Resource top, PRBool localp)
  436. {
  437.   RDFFile newFile = makeRDFFile(url, top, localp);
  438.   if (rdfFiles) {  
  439.     newFile->next = rdfFiles;
  440.     rdfFiles = newFile;
  441.   } else {
  442.     rdfFiles = newFile;
  443.   }
  444.   newFile->db = gRemoteStore;
  445.   newFile->assert = remoteAssert3;
  446.   if (top) {
  447.     if (resourceType(top) == RDF_RT) {
  448.       if (strstr(url, ".mcf")) {
  449.     newFile->fileType = RDF_MCF;
  450.       } else {
  451.     newFile->fileType = RDF_XML;
  452.       }
  453.     } else {
  454.       newFile->fileType = resourceType(top);
  455.     }
  456.   }
  457.   beginReadingRDFFile(newFile);
  458.   return newFile;
  459. }
  460.  
  461.  
  462.  
  463. void
  464. possiblyRefreshRDFFiles ()
  465. {
  466.   RDFFile f = rdfFiles;
  467.   PRTime tm = PR_Now();  
  468.   while (f != NULL) {
  469.     if (f->expiryTime != NULL) {
  470.       PRTime *expiry = f->expiryTime;
  471. #ifdef HAVE_LONG_LONG
  472.       if ((tm  - *expiry) > 0) 
  473. #else
  474.       int64 result;
  475.       LL_SUB(result, tm, *expiry);
  476.       if ((!LL_IS_ZERO(result) && LL_GE_ZERO(result)))
  477. #endif /* !HAVE_LONG_LONG */
  478.     {
  479.       gcRDFFile (f);
  480.       initRDFFile(f);
  481.       beginReadingRDFFile(f);      
  482.     } 
  483.     }
  484.     f = f->next;
  485.   }
  486.   /*  flushBookmarks(); */
  487. }
  488.