]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/acquire.cc
acquire: Use priority queues and a 3 stage pipeline design
[apt.git] / apt-pkg / acquire.cc
index e588b0306513f4cd75a73dc50e09c878b9713bb3..2ad6bc47f91c3a846ce658faeaab84acd37eda6c 100644 (file)
@@ -80,7 +80,7 @@ void pkgAcquire::Initialize()
    if (getuid() == 0 && SandboxUser.empty() == false && SandboxUser != "root") // if we aren't root, we can't chown, so don't try it
    {
       struct passwd const * const pw = getpwnam(SandboxUser.c_str());
-      struct group const * const gr = getgrnam("root");
+      struct group const * const gr = getgrnam(ROOT_GROUP);
       if (pw != NULL && gr != NULL)
       {
         std::string const AuthConf = _config->FindFile("Dir::Etc::netrc");
@@ -106,7 +106,7 @@ static bool SetupAPTPartialDirectory(std::string const &grand, std::string const
    if (getuid() == 0 && SandboxUser.empty() == false && SandboxUser != "root") // if we aren't root, we can't chown, so don't try it
    {
       struct passwd const * const pw = getpwnam(SandboxUser.c_str());
-      struct group const * const gr = getgrnam("root");
+      struct group const * const gr = getgrnam(ROOT_GROUP);
       if (pw != NULL && gr != NULL)
       {
          // chown the partial dir
@@ -894,9 +894,10 @@ pkgAcquire::Queue::~Queue()
 /* */
 bool pkgAcquire::Queue::Enqueue(ItemDesc &Item)
 {
+   QItem **OptimalI = &Items;
    QItem **I = &Items;
    // move to the end of the queue and check for duplicates here
-   for (; *I != 0; I = &(*I)->Next)
+   for (; *I != 0; ) {
       if (Item.URI == (*I)->URI)
       {
         if (_config->FindB("Debug::pkgAcquire::Worker",false) == true)
@@ -905,12 +906,22 @@ bool pkgAcquire::Queue::Enqueue(ItemDesc &Item)
         Item.Owner->Status = (*I)->Owner->Status;
         return false;
       }
+      // Determine the optimal position to insert: before anything with a
+      // higher priority.
+      int priority = (*I)->GetPriority();
+
+      I = &(*I)->Next;
+      if (priority >= Item.Owner->Priority()) {
+        OptimalI = I;
+      }
+   }
+
 
    // Create a new item
    QItem *Itm = new QItem;
    *Itm = Item;
-   Itm->Next = 0;
-   *I = Itm;
+   Itm->Next = *OptimalI;
+   *OptimalI = Itm;
    
    Item.Owner->QueueCounter++;   
    if (Items->Next == 0)
@@ -1060,16 +1071,24 @@ bool pkgAcquire::Queue::Cycle()
 
    // Look for a queable item
    QItem *I = Items;
+   int ActivePriority = 0;
    while (PipeDepth < (signed)MaxPipeDepth)
    {
-      for (; I != 0; I = I->Next)
+      for (; I != 0; I = I->Next) {
+        if (I->Owner->Status == pkgAcquire::Item::StatFetching)
+           ActivePriority = std::max(ActivePriority, I->GetPriority());
         if (I->Owner->Status == pkgAcquire::Item::StatIdle)
            break;
+      }
 
       // Nothing to do, queue is idle.
       if (I == 0)
         return true;
 
+      // This item has a lower priority than stuff in the pipeline, pretend
+      // the queue is idle
+      if (I->GetPriority() < ActivePriority)
+        return true;
       I->Worker = Workers;
       for (auto const &O: I->Owners)
         O->Status = pkgAcquire::Item::StatFetching;
@@ -1135,6 +1154,15 @@ APT_PURE unsigned long long pkgAcquire::Queue::QItem::GetMaximumSize() const     /*{
    return Maximum;
 }
                                                                        /*}}}*/
+APT_PURE int pkgAcquire::Queue::QItem::GetPriority() const     /*{{{*/
+{
+   int Priority = 0;
+   for (auto const &O: Owners)
+      Priority = std::max(Priority, O->Priority());
+
+   return Priority;
+}
+                                                                       /*}}}*/
 void pkgAcquire::Queue::QItem::SyncDestinationFiles() const            /*{{{*/
 {
    /* ensure that the first owner has the best partial file of all and
@@ -1312,7 +1340,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner)
 
       // build the status str
       std::ostringstream str;
-      str.imbue(std::locale("C.UTF-8"));
+      str.imbue(std::locale::classic());
       str.precision(4);
       str << "dlstatus" << ':' << std::fixed << i << ':' << Percent << ':' << msg << '\n';
       auto const dlstatus = str.str();