(FILECREATED " 6-Dec-85 18:48:30" {QV}<NOTECARDS>1.3K>RHTPATCH013.;3 21828  

      changes to:  (FNS NC.GetNewCard NC.PlausibleNoteFileHeaderP NC.OpenDatabaseFile 
			NC.CreateDatabaseFile NC.GetHashArray NC.InstallCardInNoteFile 
			NC.CheckForNeededConversion)
		   (VARS RHTPATCH013COMS)
		   (RECORDS NoteFile)

      previous date: " 6-Dec-85 15:54:36" {QV}<NOTECARDS>1.3K>RHTPATCH013.;1)


(* Copyright (c) 1985 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT RHTPATCH013COMS)

(RPAQQ RHTPATCH013COMS ((* * New functions for NCDATABASE)
			  (FNS NC.CheckForNeededConversion NC.PlausibleNoteFileHeaderP)
			  (* * Modified functions and stuff from NCDATABASE)
			  (RECORDS NoteFile)
			  (FNS NC.OpenDatabaseFile NC.CreateDatabaseFile NC.GetHashArray 
			       NC.InstallCardInNoteFile NC.GetNewCard)))
(* * New functions for NCDATABASE)

(DEFINEQ

(NC.CheckForNeededConversion
  (LAMBDA (NoteFile Convertw/oConfirmFlg)                    (* rht: " 6-Dec-85 15:48")

          (* * Check the version of NoteFile. If version 2, then convert if user confirms. If earlier than version 2, then 
	  bail out with informative message.)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
	  (Version (fetch (NoteFile Version) of NoteFile))
	  (FullFileName (fetch (NoteFile FullFileName) of NoteFile))
	  NewFileName)
         (COND
	   ((EQ Version 3)
	     NoteFile)
	   ((GEQ Version 4)
	     (NC.ReportError "NC.CheckForNeededConversion" (CONCAT "Version number of notefile: " 
								       FullFileName 
								       " is greater than 3."))
	     NIL)
	   ((LEQ Version 1)
	     (NC.PrintMsg NIL T "Notefile " FullFileName (" is  too old (version " Version 
").  It must first be converted to version 2 by opening in NoteCards release 1.2i. Then we convert to version 3."
										     )
			    (CHARACTER 13))
	     NIL)
	   ((AND Convertw/oConfirmFlg (NOT (NC.YesP (NC.AskUser (CONCAT "Notefile: " 
										  FullFileName 
										 " is version 2."
										  (CHARACTER 13)
										  
								 "Want to convert to version 3? ")
									NIL
									(QUOTE Yes)
									T NIL T NIL T))))
	     NIL)
	   ((SETQ NewFileName (NC.AutoloadApply* (FUNCTION NC.ConvertNoteFileVersion2To3)
						   Stream))

          (* * Things are okay. File was version 2 and has been converted to version 3)


	     (if (SETQ Stream (CAR (ERSETQ (OPENSTREAM NewFileName Access (QUOTE OLD)
								 (QUOTE ((TYPE BINARY)))))))
		 then                                      (* Redo the work at the top of NC.OpenDatabaseFile.)
			(replace (NoteFile Stream) of NoteFile with Stream)
			(replace (NoteFile FullFileName) of NoteFile with (FULLNAME Stream))
			(NC.SetMonitor NoteFile (CREATE.MONITORLOCK (MKATOM (CONCAT 
										      NewFileName 
											  ":LOCK"))))
			(NC.GetNoteFileHeader NoteFile)
			NoteFile
	       else (NC.ReportError "NC.CheckForNeededConversion" "Couldn't open " FileName 
					" after running NC.ConvertNoteFileVersion2To3."
					(CHARACTER 13))
		      NIL))
	   (T NIL)))))

(NC.PlausibleNoteFileHeaderP
  (LAMBDA (NoteFile QuietFlg)                                (* rht: " 6-Dec-85 18:05")

          (* * Return non-nil if notefile's header information seems reasonable.)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
	  (NextIndexNum (fetch (NoteFile NextIndexNum) of NoteFile))
	  (HashArraySize (fetch (NoteFile HashArraySize) of NoteFile))
	  (CheckptPtr (fetch (NoteFile CheckptPtr) of NoteFile))
	  (NextLinkNum (fetch (NoteFile NextLinkNum) of NoteFile))
	  (IndexWidth (CONSTANT (fetch (NoteFileVersion NoteFileIndexWidth) of (
								     NC.FetchCurrentVersionObject)))
		      )
	  EOFPtr)
         (SETQ EOFPtr (GETEOFPTR Stream))
         (COND
	   ((OR (LEQ NextIndexNum 0)
		  (GEQ (TIMES IndexWidth NextIndexNum)
			 EOFPtr))
	     (OR QuietFlg (NC.PrintMsg NIL T "Bad NextIndexNum (" NextIndexNum 
					   ") on notefile header."
					   (CHARACTER 13)))
	     NIL)
	   ((OR (LEQ HashArraySize 0)
		  (GEQ (TIMES IndexWidth HashArraySize)
			 EOFPtr))
	     (OR QuietFlg (NC.PrintMsg NIL T "Bad HashArraySize (" HashArraySize 
					   ") on notefile header."
					   (CHARACTER 13)))
	     NIL)
	   ((OR (LEQ CheckptPtr 0)
		  (GREATERP CheckptPtr EOFPtr))
	     (OR QuietFlg (NC.PrintMsg NIL T "Bad CheckptPtr (" CheckptPtr 
					   ") on notefile header."
					   (CHARACTER 13)))
	     NIL)
	   ((LESSP NextLinkNum 0)
	     (OR QuietFlg (NC.PrintMsg NIL T "Bad NextLinkNum (" NextLinkNum 
					   ") on notefile header."
					   (CHARACTER 13)))
	     NIL)
	   (T NoteFile)))))
)
(* * Modified functions and stuff from NCDATABASE)

[DECLARE: EVAL@COMPILE 

(DATATYPE NoteFile (UID Stream FullFileName HashArray (HashArraySize FIXP)
			  (NextIndexNum FIXP)
			  (Version BYTE)
			  (NextLinkNum FIXP)
			  (CheckptPtr FIXP)
			  LinkLabelsCard TableOfContentsCard ToBeFiledCard OrphansCard 
			  UserHashTableCard ReservedCards Menu MonitorLock ExclusiveAccessMonitor 
			  CachingProcess IndexNumsFreeList UserProps))
]
(/DECLAREDATATYPE (QUOTE NoteFile)
		  (QUOTE (POINTER POINTER POINTER POINTER FIXP FIXP BYTE FIXP FIXP POINTER POINTER 
				  POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
				  POINTER POINTER))
		  (QUOTE ((NoteFile 0 POINTER)
			  (NoteFile 2 POINTER)
			  (NoteFile 4 POINTER)
			  (NoteFile 6 POINTER)
			  (NoteFile 8 FIXP)
			  (NoteFile 10 FIXP)
			  (NoteFile 6 (BITS . 7))
			  (NoteFile 12 FIXP)
			  (NoteFile 14 FIXP)
			  (NoteFile 16 POINTER)
			  (NoteFile 18 POINTER)
			  (NoteFile 20 POINTER)
			  (NoteFile 22 POINTER)
			  (NoteFile 24 POINTER)
			  (NoteFile 26 POINTER)
			  (NoteFile 28 POINTER)
			  (NoteFile 30 POINTER)
			  (NoteFile 32 POINTER)
			  (NoteFile 34 POINTER)
			  (NoteFile 36 POINTER)
			  (NoteFile 38 POINTER)))
		  (QUOTE 40))
(DEFINEQ

(NC.OpenDatabaseFile
  (LAMBDA (NoteFileOrFileName Access Don'tCacheTypesAndTitlesFlg QuietFlg Don'tCreateFlg 
			      Convertw/oConfirmFlg Don'tCreateArrayFlg Don'tTruncateFlg 
			      Don'tCreateInterfaceFlg)       (* rht: " 6-Dec-85 18:02")

          (* * Open an already existing NoteFile and return a NoteFile object)



          (* * rht 8/7/84: For nonexistent files, asks user whether to create unless Don'tCreateFlg is non-nil.)



          (* * rht 1/9/85: Checks NC.UncachingNotCompleted global var. If non-nil, then previous notefile died unnaturally, 
	  so we first clear junk off the IDs.)



          (* * rht 8/6/85: Added Don'tTruncateFlg, which, if on, prevents the check for truncation.)



          (* * fgh 10/16/85 Updated to use new cacheing scheme.)



          (* * kirk 10/29/85: Now does cacheing of types and titles as background process.)



          (* * fkr 11/8/85: Converted from Streams to NoteFile object.)



          (* * kirk 30Nov85 Added a check for correct version number.)



          (* * rht 12/6/85: Moved Kirk's above patch to NC.CheckForNeededConversion and modified somewhat.
	  Added check for plausible header.)


    (PROG (NoteFile FileName Name Stream NewStream Card CardTotal)
	    (OR Access (SETQ Access (QUOTE BOTH)))
	    (SETQ FileName (COND
		((type? NoteFile NoteFileOrFileName)
		  (SETQ NoteFile NoteFileOrFileName)
		  (fetch (NoteFile FullFileName) of NoteFileOrFileName))
		(T (SETQ NoteFile (create NoteFile))
		   NoteFileOrFileName)))
	    (COND
	      ((NOT (OR FileName (SETQ FileName (NC.DatabaseFileName 
								      "Name of NoteFile to open:"
									     " -- " T))))
		(RETURN NIL)))
	    (COND
	      ((OPENP FileName)
		(NC.PrintMsg NIL T FileName " is an already open file." (CHARACTER 13))
		(RETURN NIL)))
	    (AND (NOT (SETQ Name (INFILEP FileName)))
		   (COND
		     (Don'tCreateFlg (NC.PrintMsg NIL T "Couldn't find NoteFile " FileName "."
						    (CHARACTER 13))
				     (RETURN NIL))
		     ((NC.YesP (NC.AskUser (CONCAT "Unable to find NoteFile " FileName "."
							 (CHARACTER 13)
							 "Want to create new NoteFile by that name? ")
					       " -- " "Yes" T NIL T NIL T))
		       (NC.CreateDatabaseFile FileName NIL "Opening NoteFile" T)
		       (AND (NOT (SETQ Name (INFILEP FileName)))
			      (NC.PrintMsg NIL T "Still unable to find Notefile " FileName "."
					     (CHARACTER 13))
			      (RETURN NIL)))
		     (T (RETURN NIL))))
	    (AND (NULL QuietFlg)
		   (NC.PrintMsg NIL T "Opening ... " (CHARACTER 13)))
	    (COND
	      ((NULL (SETQ Stream (CAR (ERSETQ (OPENSTREAM Name Access (QUOTE OLD)
								     (QUOTE ((TYPE BINARY))))))))
		(NC.PrintMsg NIL T "Couldn't open " FileName "." (CHARACTER 13))
		(RETURN NIL)))
	    (replace (NoteFile Stream) of NoteFile with Stream)
	    (replace (NoteFile FullFileName) of NoteFile with (FULLNAME Stream))
	    (NC.SetMonitor NoteFile (CREATE.MONITORLOCK (MKATOM (CONCAT Name ":LOCK"))))
	    (NC.GetNoteFileHeader NoteFile)                (* See if notefile is out of date.
							     If so, convert to current version.)
	    (if (NOT (NC.CheckForNeededConversion NoteFile Convertw/oConfirmFlg))
		then (CLOSEF (fetch (NoteFile Stream) of NoteFile))
		       (NC.PrintMsg NIL NIL "Open cancelled.")
		       (RETURN NIL))                       (* See if notefile header seems reasonable.
							     If not, bail out.)
	    (if (NOT (NC.PlausibleNoteFileHeaderP NoteFile))
		then (NC.PrintMsg NIL NIL 
				      "Notefile has bad header.  Please see a NoteCards wizard."
				      (CHARACTER 13)
				      "Open cancelled.")
		       (RETURN NIL))
	    (COND
	      ((NULL Don'tTruncateFlg)                     (* Can either bail out entirely or run inspector and 
							     then bail out.)
		(SELECTQ (SETQ NewStream (NC.CheckForNeededTruncation NoteFile Access))
			   (ABORT (CLOSEF Stream)
				  (NC.PrintMsg NIL T "Open cancelled.")
				  (RETURN NIL))
			   (ABORTANDINSPECT (CLOSEF Stream)
					    (NC.ScavengerPhase1 Name)
					    (RETURN NIL))
			   NIL)
		(AND (STREAMP NewStream)
		       (replace (NoteFile Stream) of NoteFile with NewStream))))
	    (OR Don'tCreateArrayFlg (NC.BuildHashArray NoteFile))

          (* * Make sure the NF can't be closed by CLOSEALL)


	    (WHENCLOSE (fetch (NoteFile Stream) of NoteFile)
			 (QUOTE CLOSEALL)
			 (QUOTE NO))
	    (COND
	      ((NULL Don'tCacheTypesAndTitlesFlg)          (* Cache all of the titles in this database)
		(replace (NoteFile CachingProcess) of NoteFile
		   with (ADD.PROCESS (LIST (FUNCTION NC.CacheTypesAndTitles)
						 NoteFile)))))
                                                             (* Stash the special cards into the NoteFile object.)
	    (NC.GetSpecialCards NoteFile)                  (* Stash the notefile in the global notefiles hash 
							     array.)
	    (NC.StoreNoteFile NoteFile)
	    (COND
	      ((NULL Don'tCreateInterfaceFlg)              (* Make an interface menu for this notefile.)
		(NC.SetUpNoteFileInterface NoteFile)))
	    (AND (NULL QuietFlg)
		   (NC.PrintMsg NIL T "Opened " (FULLNAME Stream)
				  (CHARACTER 13)))
	    (SETQ NC.LastNoteFileOpened NoteFile)
	    (RETURN NoteFile))))

(NC.CreateDatabaseFile
  (LAMBDA (FileName HashArraySize CallingOperationMsg OmitFinalNoteFlg StartingNextFreeIndex)
                                                             (* rht: " 6-Dec-85 17:54")

          (* * Create a NoteCards database on file FileName. Just creates an index HashArraySize entries long, then writes 
	  out the Root and Orphan cards)



          (* * rht 8/7/84: Added OmitFinalNoteFlg flag parameter to prevent the final message. Changed parameter name from 
	  NC.IndexSizeInEntries to HashArraySize since the fomer is a global.)



          (* * rht 1/30/85: Reserved 3 bytes of the remaining 8 to hold pointer to last checkpointed EOFPTR.)



          (* * rht 3/21/85: Added the StartingNextFreeIndex argument which if non-nil, gives a NextID Num to be filled in to 
	  the file before returning. This is useful when compacting.)



          (* * fkr 11/8/85: Added check that OPENSTREAM succeeded. Added call to NC.CreateNoteFileObject in which lots of 
	  work is now being done.)



          (* * fgh 11/17/85 Wrapped whole thing in ERSETQ to close file if somethinghappens during the create.)



          (* * kirk 30Nov85 Added check for correct version number)



          (* * rht 12/6/85: Fixed call to OPENSTREAM to peel off version number.)


    (LET (Stream NoteFile)
         (OR (CAR (ERSETQ (PROG NIL
				        (SETQ CallingOperationMsg (COND
					    (CallingOperationMsg (CONCAT CallingOperationMsg
									   (CHARACTER 13)))
					    (T "")))
				        (AND (NULL FileName)
					       (NULL (SETQ FileName (NC.DatabaseFileName 
						"What is the name of the NoteFile to be created?"
											       " -- " 
											       T T)))
					       (RETURN (QUOTE CANCELLED)))
				        (OR (FIXP HashArraySize)
					      (SETQ HashArraySize NC.DefaultIndexSizeInEntries))
				        (COND
					  ((NULL (SETQ Stream
						     (CAR (ERSETQ (OPENSTREAM
									(PACKFILENAME (QUOTE
											  VERSION)
											NIL
											(QUOTE
											  BODY)
											FileName)
									(QUOTE BOTH)
									(QUOTE NEW)
									(QUOTE ((TYPE BINARY))))))))
					    (NC.PrintMsg NIL T "Can't open file: " FileName
							   (CHARACTER 13)
							   "Create cancelled."
							   (CHARACTER 13))
					    (RETURN (QUOTE CANCELLED))))
				        (RESETSAVE NIL (BQUOTE (PROGN (CLOSEF , Stream)
									    (DELFILE (FULLNAME
											 , Stream)))))
				        (NC.PrintMsg NIL T CallingOperationMsg "Creating NoteFile "
						       (FULLNAME Stream)
						       ".  Please wait...  ")
				        (SETQ NoteFile
					  (create NoteFile
						    UID ←(NC.MakeUID)
						    Stream ← Stream
						    FullFileName ←(FULLNAME Stream)
						    HashArray ←(HASHARRAY HashArraySize)
						    HashArraySize ← HashArraySize
						    NextIndexNum ←(OR
						      (FIXP StartingNextFreeIndex)
						      (CONSTANT (ADD1 (fetch (NoteFileVersion
										     
									    NumberOfReservedCards)
									     of (
								     NC.FetchCurrentVersionObject)))
								  ))
						    Version ← NC.VersionNumber
						    NextLinkNum ← 1
						    CheckptPtr ←(NC.TotalIndexSize HashArraySize)
						    MonitorLock ←(CREATE.MONITORLOCK (QUOTE
											 Creating))))
                                                             (* Write the header down to the file.)
				        (NC.PutNoteFileHeader NoteFile)
				        (NC.PrintMsg NIL T CallingOperationMsg "Creating NoteFile."
						       (CHARACTER 13)
						       "Processing item " 1 " out of " HashArraySize 
						       "."
						       (CHARACTER 13))
				        (for CTR from 1 to HashArraySize eachtime (BLOCK)
					   do (AND (ZEROP (IREMAINDER CTR 1000))
						       (NC.PrintMsg NIL T CallingOperationMsg 
								      "Creating NoteFile."
								      (CHARACTER 13)
								      "Processing item " CTR 
								      " out of "
								      HashArraySize "." (CHARACTER
									13)))
						(NC.WriteStatus Stream (QUOTE FREE))
						(SETFILEPTR
						  Stream
						  (PLUS (GETFILEPTR Stream)
							  (CONSTANT (SUB1 (fetch (
NoteFileVersion NoteFileIndexWidth) of (NC.FetchCurrentVersionObject)))))))
				        (NC.PrintMsg NIL T CallingOperationMsg "Creating NoteFile "
						       (FULLNAME Stream)
						       ".  Please wait...  ")
                                                             (* Move NextIndexNum back to the beginning so that 
							     special cards will have the correct index nums.)
				        (replace (NoteFile NextIndexNum) of NoteFile
					   with 1)
				        (NC.InitializeSpecialCards NoteFile)
				        (NC.CheckpointDatabase NoteFile T)
				        (NC.ForceDatabaseClose NoteFile)
				        (SETQ NC.DatabaseFileNameSuggestion (PACKFILENAME
					    (QUOTE VERSION)
					    NIL
					    (QUOTE BODY)
					    (FULLNAME FileName)))
				        (COND
					  (OmitFinalNoteFlg (NC.PrintMsg NIL NIL "  Done!"
									   (CHARACTER 13)))
					  (T (NC.PrintMsg NIL NIL "  Done!" (CHARACTER 13)
							    "Note that the NoteFile must still" 
							    " be opened before it is used."
							    (CHARACTER 13))))
				        (RETURN NoteFile))))
	       (CLOSEF Stream (DELFILE (FULLNAME Stream)))
	       (QUOTE CANCELLED)))))

(NC.GetHashArray
  (LAMBDA (NoteFile QuietFlg OperationMsg)                   (* rht: " 6-Dec-85 18:07")

          (* * Fill NoteFile's hash array by reading from the index on NoteFile.)



          (* * rht 12/6/85: Fixed to build free list of IndexNum's.)


    (OR OperationMsg (SETQ OperationMsg ""))
    (WITH.MONITOR (NC.FetchMonitor NoteFile)
		  (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
			(CardTotal (SUB1 (fetch (NoteFile NextIndexNum) of NoteFile)))
			IndexNumsFreeList)
		       (OR QuietFlg (NC.PrintMsg NIL T OperationMsg 
						     "Reading in hash array: item number "
						     1 " out of " CardTotal "." (CHARACTER 13)))
		       (SETFILEPTR Stream (CONSTANT (fetch (NoteFileVersion NoteFileHeaderSize)
							   of (NC.FetchCurrentVersionObject))))
		       (for IndexNum from 1 to CardTotal bind Card eachtime (BLOCK)
			  do (OR QuietFlg (AND (ZEROP (REMAINDER IndexNum 100))
						     (NC.PrintMsg NIL T OperationMsg 
							    "Reading in hash array: item number "
								    IndexNum " out of " CardTotal "."
								    (CHARACTER 13))))
			       (SETQ Card (NC.ReadIndexEntry NoteFile))
			       (if (EQ (fetch (Card Status) of Card)
					   (QUOTE FREE))
				   then (push IndexNumsFreeList IndexNum)))
		       (replace (NoteFile IndexNumsFreeList) of NoteFile with IndexNumsFreeList)
		    ))))

(NC.InstallCardInNoteFile
  (LAMBDA (Card NoteFile)                                    (* rht: " 6-Dec-85 16:56")

          (* * Put Card into NoteFile's hash array.)


    (PUTHASH (fetch (Card UID) of Card)
	       Card
	       (fetch (NoteFile HashArray) of NoteFile))
    Card))

(NC.GetNewCard
  (LAMBDA (NoteFile DontUpdateFlg)                           (* rht: " 6-Dec-85 17:12")

          (* * rht 1/9/85: Keep track of the total number of cards in NC.UncachingNotCompleted.)



          (* * rht 1/31/85: Increases array size if needed. Also now stores highest ID number in a global var and only writes
	  to the file at checkpoint time.)



          (* * rht 2/1/85: Now warn user if within 90% of index full. Also if index array is full, then increase its size.)



          (* * fgh 10/15/85 increase cache arry size when necessary)



          (* * rht 11/12/85: Updated to handle NoteFile format.)



          (* * rht 12/6/85: Fixed to reuse free index num if any. Find these on IndexNumsFreeList.)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
	  (NextIndexNum (fetch (NoteFile NextIndexNum) of NoteFile))
	  (IndexSize (fetch (NoteFile HashArraySize) of NoteFile))
	  (IndexNumsFreeList (fetch (NoteFile IndexNumsFreeList) of NoteFile))
	  IndexNum UID Card PercentUsed)
         (if IndexNumsFreeList
	     then (SETQ IndexNum (pop IndexNumsFreeList))
		    (replace (NoteFile IndexNumsFreeList) of NoteFile with IndexNumsFreeList)
	   else (SETQ IndexNum NextIndexNum)
		  (replace (NoteFile NextIndexNum) of NoteFile with (ADD1 NextIndexNum)))
         (if (GREATERP (SETQ PercentUsed (FIX (TIMES 100 (QUOTIENT (FLOAT NextIndexNum)
									       (FLOAT IndexSize)))))
			   90)
	     then (NC.PrintMsg NIL T "Index for notefile: " (FULLNAME Stream)
				   " is " PercentUsed "%% full." (CHARACTER 13)
				   "Please close notefile soon and compact."))
         (if (EQ NextIndexNum IndexSize)
	     then (NC.ReportError "NC.GetNewCard" "Index full."))
         (SETQ Card (create Card
				UID ←(NC.MakeUID)
				NoteFile ← NoteFile
				IndexLoc ←(NC.NoteFileLocFromIndexNum IndexNum)
				IndexDirtyFlg ← T))
         (NC.InstallCardInNoteFile Card NoteFile)
     Card)))
)
(PUTPROPS RHTPATCH013 COPYRIGHT ("Xerox Corporation" 1985))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (876 4976 (NC.CheckForNeededConversion 886 . 3253) (NC.PlausibleNoteFileHeaderP 3255 . 
4974)) (6220 21746 (NC.OpenDatabaseFile 6230 . 12034) (NC.CreateDatabaseFile 12036 . 17768) (
NC.GetHashArray 17770 . 19295) (NC.InstallCardInNoteFile 19297 . 19612) (NC.GetNewCard 19614 . 21744))
)))
STOP