+\r
+//\r
+// The current Hii implementation accesses this variable a larg # of times on every boot.\r
+// Other common variables are only accessed a single time. This is why this cache algorithm\r
+// only targets a single variable. Probably to get an performance improvement out of\r
+// a Cache you would need a cache that improves the search performance for a variable.\r
+//\r
+VARIABLE_CACHE_ENTRY mVariableCache[] = {\r
+ {\r
+ &gEfiGlobalVariableGuid,\r
+ L"Lang",\r
+ 0x00000000,\r
+ 0x00,\r
+ NULL\r
+ }\r
+};\r
+\r
+\r
+/**\r
+ Update the Cache with Variable information. These are the same \r
+ arguments as the EFI Variable services.\r
+\r
+ @param[in] VariableName Name of variable\r
+ @param[in] VendorGuid Guid of variable\r
+ @param[in] Attribute Attribue of the variable\r
+ @param[in] DataSize Size of data. 0 means delete\r
+ @param[in] Data Variable data\r
+\r
+**/\r
+VOID\r
+UpdateVariableCache (\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ IN UINT32 Attributes,\r
+ IN UINTN DataSize,\r
+ IN VOID *Data\r
+ )\r
+{\r
+ VARIABLE_CACHE_ENTRY *Entry;\r
+ UINTN Index;\r
+\r
+ if (EfiAtRuntime ()) {\r
+ // Don't use the cache at runtime\r
+ return;\r
+ }\r
+\r
+ for (Index = 0, Entry = mVariableCache; Index < sizeof (mVariableCache)/sizeof (VARIABLE_CACHE_ENTRY); Index++, Entry++) {\r
+ if (CompareGuid (VendorGuid, Entry->Guid)) {\r
+ if (StrCmp (VariableName, Entry->Name) == 0) { \r
+ Entry->Attributes = Attributes;\r
+ if (DataSize == 0) {\r
+ // Delete Case\r
+ if (Entry->DataSize != 0) {\r
+ FreePool (Entry->Data);\r
+ }\r
+ Entry->DataSize = DataSize;\r
+ } else if (DataSize == Entry->DataSize) {\r
+ CopyMem (Entry->Data, Data, DataSize);\r
+ } else {\r
+ Entry->Data = AllocatePool (DataSize);\r
+ Entry->DataSize = DataSize;\r
+ CopyMem (Entry->Data, Data, DataSize);\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Search the cache to see if the variable is in the cache.\r
+\r
+ @param[in] VariableName Name of variable\r
+ @param[in] VendorGuid Guid of variable\r
+ @param[in] Attribute Attribue returned \r
+ @param[in] DataSize Size of data returned\r
+ @param[in] Data Variable data returned\r
+\r
+ @retval EFI_SUCCESS VariableGuid & VariableName data was returned.\r
+ @retval other Not found.\r
+\r
+**/\r
+EFI_STATUS\r
+FindVariableInCache (\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_GUID *VendorGuid,\r
+ OUT UINT32 *Attributes OPTIONAL,\r
+ IN OUT UINTN *DataSize,\r
+ OUT VOID *Data\r
+ )\r
+{\r
+ VARIABLE_CACHE_ENTRY *Entry;\r
+ UINTN Index;\r
+\r
+ if (EfiAtRuntime ()) {\r
+ // Don't use the cache at runtime\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ for (Index = 0, Entry = mVariableCache; Index < sizeof (mVariableCache)/sizeof (VARIABLE_CACHE_ENTRY); Index++, Entry++) {\r
+ if (CompareGuid (VendorGuid, Entry->Guid)) {\r
+ if (StrCmp (VariableName, Entry->Name) == 0) {\r
+ if (Entry->DataSize == 0) {\r
+ // Variable was deleted so return not found\r
+ return EFI_NOT_FOUND;\r
+ } else if (Entry->DataSize != *DataSize) {\r
+ // If the buffer is too small return correct size\r
+ *DataSize = Entry->DataSize;\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ } else {\r
+ // Return the data\r
+ CopyMem (Data, Entry->Data, Entry->DataSize);\r
+ if (Attributes != NULL) {\r
+ *Attributes = Entry->Attributes;\r
+ }\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+\r